From 4a74f574ff4241613a9e8ece5d1048115db0ee0e Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 8 Sep 2021 15:19:34 +0800 Subject: [PATCH 01/94] fix codestyle Signed-off-by: ma_nan --- services/applypatch/partition_record.cpp | 8 ++++---- services/applypatch/transfer_manager.cpp | 17 ++++++++++------- services/include/applypatch/partition_record.h | 4 ++-- services/ui/text_label.cpp | 16 ++++++++-------- services/ui/text_label.h | 4 ++++ 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/services/applypatch/partition_record.cpp b/services/applypatch/partition_record.cpp index 9d758176..f00aea61 100644 --- a/services/applypatch/partition_record.cpp +++ b/services/applypatch/partition_record.cpp @@ -31,9 +31,9 @@ bool PartitionRecord::IsPartitionUpdated(const std::string &partitionName) { auto miscBlockDevice = GetMiscPartitionPath(); uint8_t buffer[PARTITION_UPDATER_RECORD_MSG_SIZE]; - char *realPath = realpath(miscBlockDevice.c_str(), NULL); - UPDATER_FILE_CHECK(realPath != nullptr, "realPath is NULL", return false); if (!miscBlockDevice.empty()) { + char *realPath = realpath(miscBlockDevice.c_str(), NULL); + UPDATER_FILE_CHECK(realPath != nullptr, "realPath is NULL", return false); int fd = open(realPath, O_RDONLY | O_EXCL | O_CLOEXEC | O_BINARY); free(realPath); UPDATER_FILE_CHECK(fd >= 0, "PartitionRecord: Open misc to recording partition failed", return false); @@ -60,9 +60,9 @@ bool PartitionRecord::IsPartitionUpdated(const std::string &partitionName) bool PartitionRecord::RecordPartitionUpdateStatus(const std::string &partitionName, bool updated) { auto miscBlockDevice = GetMiscPartitionPath(); - char *realPath = realpath(miscBlockDevice.c_str(), NULL); - UPDATER_FILE_CHECK(realPath != nullptr, "realPath is NULL", return false); if (!miscBlockDevice.empty()) { + char *realPath = realpath(miscBlockDevice.c_str(), NULL); + UPDATER_FILE_CHECK(realPath != nullptr, "realPath is NULL", return false); int fd = open(realPath, O_RDWR | O_EXCL | O_CLOEXEC | O_BINARY); free(realPath); UPDATER_FILE_CHECK(fd >= 0, "PartitionRecord: Open misc to recording partition failed", return false); diff --git a/services/applypatch/transfer_manager.cpp b/services/applypatch/transfer_manager.cpp index bb2746c1..e98cddb5 100644 --- a/services/applypatch/transfer_manager.cpp +++ b/services/applypatch/transfer_manager.cpp @@ -58,12 +58,13 @@ bool TransferManager::CommandsParser(int fd, const std::vector &con globalParams->blockCount = utils::String2Int(*ct++, utils::N_DEC); globalParams->maxEntries = utils::String2Int(*ct++, utils::N_DEC); globalParams->maxBlocks = utils::String2Int(*ct++, utils::N_DEC); - size_t totalSize = globalParams->maxBlocks * globalParams->blockCount; + size_t totalSize = globalParams->blockCount; std::string retryCmd = ""; if (globalParams != nullptr && globalParams->env != nullptr && globalParams->env->IsRetry()) { retryCmd = ReloadForRetry(); } std::unique_ptr cmd; + int initBlock = 0; while (ct != context.end()) { cmd = std::make_unique(); UPDATER_ERROR_CHECK(cmd != nullptr, "Failed to parse command line.", return false); @@ -82,18 +83,21 @@ bool TransferManager::CommandsParser(int fd, const std::vector &con cmd->SetFileDescriptor(fd); std::unique_ptr cf = CommandFunctionFactory::GetCommandFunction(cmd->GetCommandType()); UPDATER_ERROR_CHECK(cf != nullptr, "Failed to get cmd exec", return false); - CommandResult ret = cf->Execute(const_cast(*cmd.get())); + CommandResult ret = cf->Execute(const_cast(*cmd.get())); CommandFunctionFactory::ReleaseCommandFunction(cf); if (CheckResult(ret, cmd->GetCommandLine(), cmd->GetCommandType()) == false) { return false; } - + if (initBlock == 0) { + initBlock = globalParams->written; + } bool typeResult = cmd->GetCommandType() == CommandType::NEW || cmd->GetCommandType() == CommandType::IMGDIFF || - cmd->GetCommandType() == CommandType::BSDIFF; + cmd->GetCommandType() == CommandType::BSDIFF || + cmd->GetCommandType() == CommandType::ZERO; if (totalSize != 0 && globalParams->env != nullptr && typeResult) { - globalParams->env->PostMessage("set_progress", - std::to_string((float)globalParams->written / totalSize)); + globalParams->env->PostMessage("set_progress", + std::to_string((float)(globalParams->written - initBlock) / totalSize)); } LOG(INFO) << "Running command : " << cmd->GetArgumentByPos(0) << " success"; } @@ -121,7 +125,6 @@ bool TransferManager::RegisterForRetry(const std::string &cmd) UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Write retry flag error"); fsync(fd); close(fd); - return ret; } diff --git a/services/include/applypatch/partition_record.h b/services/include/applypatch/partition_record.h index 916863f4..d3418992 100644 --- a/services/include/applypatch/partition_record.h +++ b/services/include/applypatch/partition_record.h @@ -72,7 +72,7 @@ private: // offset of partition record in misc. // offset is not start from zero, but // start from the global offset of misc partition. - size_t offset_; + off_t offset_; }; } // namespace updater -#endif // UPDATER_PARTITION_UPDATE_RECORD_H \ No newline at end of file +#endif // UPDATER_PARTITION_UPDATE_RECORD_H diff --git a/services/ui/text_label.cpp b/services/ui/text_label.cpp index 0b87320e..0c1343b3 100644 --- a/services/ui/text_label.cpp +++ b/services/ui/text_label.cpp @@ -101,8 +101,7 @@ void TextLabel::InitFont() png_structp fontPngPtr = nullptr; int fontBitDepth = 0; int fontColorType = 0; - uint32_t offset = 2; - UPDATER_CHECK_ONLY_RETURN(!memset_s(resPath, MAX_TEXT_SIZE + offset, 0, MAX_TEXT_SIZE + 1), return); + UPDATER_CHECK_ONLY_RETURN(!memset_s(resPath, MAX_TEXT_SIZE + offset_, 0, MAX_TEXT_SIZE + 1), return); switch (fontType_) { case DEFAULT_FONT: UPDATER_CHECK_ONLY_RETURN(snprintf_s(resPath, sizeof(resPath), sizeof(resPath) -1, "/resources/%s.png", @@ -115,8 +114,7 @@ void TextLabel::InitFont() } FILE* fp = fopen(resPath, "rb"); UPDATER_ERROR_CHECK(fp, "open font failed!", return); - const int headerNumber = 8; - uint8_t header[headerNumber]; + uint8_t header[headerNumber_]; size_t bytesRead = fread(header, 1, sizeof(header), fp); UPDATER_ERROR_CHECK(bytesRead == sizeof(header), "read header failed!", fclose(fp); return); if (png_sig_cmp(header, 0, sizeof(header))) { @@ -135,14 +133,16 @@ void TextLabel::InitFont() png_get_IHDR(fontPngPtr, fontInfoPtr, &fontWidth, &fontHeight, &fontBitDepth, &fontColorType, nullptr, nullptr, nullptr); fontChannels = png_get_channels(fontPngPtr, fontInfoPtr); - const int defaultFontBitDepth = 8; - if (fontBitDepth <= defaultFontBitDepth && fontChannels == 1 && fontColorType == PNG_COLOR_TYPE_GRAY) { + if (fontBitDepth <= defaultFontBitDepth_ && fontChannels == 1 && fontColorType == PNG_COLOR_TYPE_GRAY) { png_set_expand_gray_1_2_4_to_8(fontPngPtr); } - const int defaultFontWidth = 96; - fontWidth_ = fontWidth / defaultFontWidth; + fontWidth_ = fontWidth / defaultFontWidth_; fontHeight_ = fontHeight >> 1; PNGReadRow(fontWidth_, fontHeight_, fontPngPtr, fontBuf_); + if (fp != nullptr) { + fclose(fp); + fp = nullptr; + } } void TextLabel::SetText(const char *str) diff --git a/services/ui/text_label.h b/services/ui/text_label.h index 39f4d1b2..82d5fb9a 100644 --- a/services/ui/text_label.h +++ b/services/ui/text_label.h @@ -75,6 +75,10 @@ private: char fontBuf_[MAX_FONT_BUFFER_SIZE_HW * FONT_BUFFER_SIZE] {}; unsigned int fontWidth_ = 0; unsigned int fontHeight_ = 0; + uint32_t offset_ = 2; + const int defaultFontWidth_ = 96; + const int defaultFontBitDepth_ = 8; + const int headerNumber_ = 8; }; } // namespace updater #endif -- Gitee From b1845866570655235161801f655e1456571062a7 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 8 Sep 2021 15:28:41 +0800 Subject: [PATCH 02/94] fix codestyle Signed-off-by: ma_nan --- services/updater_main.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/services/updater_main.cpp b/services/updater_main.cpp index 56d98839..d94b41d9 100644 --- a/services/updater_main.cpp +++ b/services/updater_main.cpp @@ -264,6 +264,15 @@ static UpdaterStatus StartUpdater(PkgManager::PkgManagerPtr manager, const std:: return StartUpdaterEntry(manager, args, upParams); } +static bool IsDir(const std::string &path) +{ + struct stat st{}; + if (stat(path.c_str(), &st) < 0) { + return false; + } + return S_ISDIR(st.st_mode); +} + static bool DeleteUpdaterPath(const std::string &path) { auto pDir = std::unique_ptr(opendir(path.c_str()), closedir); @@ -276,7 +285,7 @@ static bool DeleteUpdaterPath(const std::string &path) if (currentName[0] != '.' && (currentName.compare("log") != 0)) { std::string tmpName(path); tmpName.append("/" + currentName); - if (tmpName.find(".") == std::string::npos) { + if (IsDir(tmpName)) { DeleteUpdaterPath(tmpName); } #ifndef UPDATER_UT -- Gitee From edf419ce304ae1b2a428384256ea8f37bef1d72a Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 8 Sep 2021 20:08:25 +0800 Subject: [PATCH 03/94] fix codestyle Signed-off-by: ma_nan --- services/ui/drm_driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h index 62b5385f..d12b6742 100644 --- a/services/ui/drm_driver.h +++ b/services/ui/drm_driver.h @@ -51,7 +51,7 @@ private: int fd_; drmModeConnector *conn_; drmModeRes *res_; - struct BufferObject buff_; + struct BufferObject buff_ {}; }; } // namespace updater #endif -- Gitee From cc24af1f232dd22507aeb018895d1a0ec4e9b4ea Mon Sep 17 00:00:00 2001 From: ma_nan Date: Thu, 9 Sep 2021 14:42:52 +0800 Subject: [PATCH 04/94] fix bug Signed-off-by: ma_nan --- services/applypatch/block_set.cpp | 2 +- services/applypatch/transfer_manager.cpp | 4 ++-- services/include/applypatch/transfer_manager.h | 1 + services/updater_binary/update_image_block.cpp | 5 +++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/services/applypatch/block_set.cpp b/services/applypatch/block_set.cpp index b1670a93..b267cfb7 100644 --- a/services/applypatch/block_set.cpp +++ b/services/applypatch/block_set.cpp @@ -228,7 +228,7 @@ int32_t BlockSet::LoadSourceBuffer(const Command &cmd, size_t &pos, std::vector< LOG(INFO) << "new start to read source block ..."; UPDATER_CHECK_ONLY_RETURN(srcBlk.ReadDataFromBlock(cmd.GetFileDescriptor(), sourceBuffer) > 0, return -1); std::string nextArgv = cmd.GetArgumentByPos(pos++); - UPDATER_CHECK_ONLY_RETURN(nextArgv != "", return 0); + UPDATER_CHECK_ONLY_RETURN(nextArgv != "", return 1); BlockSet locations; locations.ParserAndInsert(nextArgv); MoveBlock(sourceBuffer, locations, sourceBuffer); diff --git a/services/applypatch/transfer_manager.cpp b/services/applypatch/transfer_manager.cpp index e98cddb5..00d88b48 100644 --- a/services/applypatch/transfer_manager.cpp +++ b/services/applypatch/transfer_manager.cpp @@ -116,7 +116,7 @@ void TransferManager::Init() bool TransferManager::RegisterForRetry(const std::string &cmd) { - std::string path = globalParams->storeBase + "/" + "retry_flag"; + std::string path = globalParams->retryFile; int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); UPDATER_ERROR_CHECK(fd != -1, "Failed to create", return false); UPDATER_ERROR_CHECK(fchown(fd, O_USER_GROUP_ID, O_USER_GROUP_ID) == 0, @@ -130,7 +130,7 @@ bool TransferManager::RegisterForRetry(const std::string &cmd) std::string TransferManager::ReloadForRetry() const { - std::string path = globalParams->storeBase + "/" + "retry_flag"; + std::string path = globalParams->retryFile; int fd = open(path.c_str(), O_RDONLY); UPDATER_ERROR_CHECK(fd >= 0, "Failed to open", return ""); (void)lseek(fd, 0, SEEK_SET); diff --git a/services/include/applypatch/transfer_manager.h b/services/include/applypatch/transfer_manager.h index 4d63a04d..3231917f 100644 --- a/services/include/applypatch/transfer_manager.h +++ b/services/include/applypatch/transfer_manager.h @@ -50,6 +50,7 @@ struct TransferParams { std::unique_ptr writerThreadInfo; int storeCreated; std::string storeBase; + std::string retryFile; uint8_t *patchDataBuffer; size_t patchDataSize; }; diff --git a/services/updater_binary/update_image_block.cpp b/services/updater_binary/update_image_block.cpp index 4e049fd2..cd042792 100644 --- a/services/updater_binary/update_image_block.cpp +++ b/services/updater_binary/update_image_block.cpp @@ -167,13 +167,14 @@ static int32_t GetUpdateBlockInfo(struct UpdateBlockInfo &infos, uscript::UScrip } static int32_t ExecuteTransferCommand(int fd, const std::vector &lines, uscript::UScriptEnv &env, - uscript::UScriptContext &context) + uscript::UScriptContext &context, const std::string &partitionName) { TransferManagerPtr tm = TransferManager::GetTransferManagerInstance(); auto globalParams = tm->GetGlobalParams(); auto writerThreadInfo = globalParams->writerThreadInfo.get(); globalParams->storeBase = "/data/updater/update_tmp"; + globalParams->retryFile = std::string("/data/updater") + partitionName + "_retry"; LOG(INFO) << "Store base path is " << globalParams->storeBase; int32_t ret = Store::CreateNewSpace(globalParams->storeBase, !globalParams->env->IsRetry()); UPDATER_ERROR_CHECK(ret != -1, "Error to create new store space", @@ -247,7 +248,7 @@ static int32_t DoExecuteUpdateBlock(UpdateBlockInfo &infos, uscript::UScriptEnv int fd = open(infos.devPath.c_str(), O_RDWR | O_LARGEFILE); UPDATER_ERROR_CHECK (fd != -1, "Failed to open block", env.GetPkgManager()->ClosePkgStream(outStream); return USCRIPT_ERROR_EXECUTE); - int32_t ret = ExecuteTransferCommand(fd, lines, env, context); + int32_t ret = ExecuteTransferCommand(fd, lines, env, context, infos.partitionName); fsync(fd); close(fd); fd = -1; -- Gitee From ab48f8f009e9d856dcbf150d44c18e1c93c03087 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Tue, 14 Sep 2021 17:22:05 +0800 Subject: [PATCH 05/94] fix codestyle Signed-off-by: ma_nan --- services/updater.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/services/updater.cpp b/services/updater.cpp index 43fb6b6f..94e7afac 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -122,11 +122,12 @@ static UpdaterStatus IsSpaceCapacitySufficient(const std::string &packagePath) UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return UPDATE_CORRUPT); std::vector fileIds; int ret = pkgManager->LoadPackageWithoutUnPack(packagePath, fileIds); - UPDATER_ERROR_CHECK(ret == PKG_SUCCESS, "LoadPackageWithoutUnPack failed", return UPDATE_CORRUPT); + UPDATER_ERROR_CHECK(ret == PKG_SUCCESS, "LoadPackageWithoutUnPack failed", + PkgManager::ReleasePackageInstance(pkgManager); return UPDATE_CORRUPT); const FileInfo *info = pkgManager->GetFileInfo("update.bin"); - UPDATER_ERROR_CHECK(info != nullptr, "update.bin is not exist", return UPDATE_CORRUPT); - + UPDATER_ERROR_CHECK(info != nullptr, "update.bin is not exist", + PkgManager::ReleasePackageInstance(pkgManager); return UPDATE_CORRUPT); PkgManager::ReleasePackageInstance(pkgManager); struct statvfs64 updaterVfs; -- Gitee From 83d46d6fa15e2536d2aaa06ca13ffccbbc3b76fc Mon Sep 17 00:00:00 2001 From: ma_nan Date: Tue, 14 Sep 2021 21:19:54 +0800 Subject: [PATCH 06/94] fix codestyle Signed-off-by: ma_nan --- services/ui/text_label.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/services/ui/text_label.cpp b/services/ui/text_label.cpp index 0c1343b3..d94a90a6 100644 --- a/services/ui/text_label.cpp +++ b/services/ui/text_label.cpp @@ -78,6 +78,15 @@ static void PngInitSet(png_structp fontPngPtr, FILE *fp, int size, png_infop fon return; } +static void CheckInitFont(png_structp fontPngPtr, FILE *fp, png_infop fontInfoPtr) +{ + png_destroy_read_struct(&fontPngPtr, &fontInfoPtr, 0); + if (fp != nullptr) { + fclose(fp); + fp = nullptr; + } +} + static void PNGReadRow(png_uint_32 fontWidth, png_uint_32 fontHeight, png_structp fontPngPtr, char *fontBuf) { if ((fontWidth > MAX_FONT_BUFFER_SIZE_HW) || (fontHeight > MAX_FONT_BUFFER_SIZE_HW)) { @@ -97,7 +106,6 @@ void TextLabel::InitFont() png_infop fontInfoPtr = nullptr; png_uint_32 fontWidth = 0; png_uint_32 fontHeight = 0; - png_byte fontChannels = 0; png_structp fontPngPtr = nullptr; int fontBitDepth = 0; int fontColorType = 0; @@ -126,23 +134,21 @@ void TextLabel::InitFont() UPDATER_ERROR_CHECK(fontPngPtr, "creat font ptr_ failed!", fclose(fp); return); fontInfoPtr = png_create_info_struct(fontPngPtr); if (fontInfoPtr == nullptr) { + png_destroy_read_struct(&fontPngPtr, nullptr, nullptr); fclose(fp); return; } PngInitSet(fontPngPtr, fp, sizeof(header), fontInfoPtr); png_get_IHDR(fontPngPtr, fontInfoPtr, &fontWidth, &fontHeight, &fontBitDepth, &fontColorType, nullptr, nullptr, nullptr); - fontChannels = png_get_channels(fontPngPtr, fontInfoPtr); + png_byte fontChannels = png_get_channels(fontPngPtr, fontInfoPtr); if (fontBitDepth <= defaultFontBitDepth_ && fontChannels == 1 && fontColorType == PNG_COLOR_TYPE_GRAY) { png_set_expand_gray_1_2_4_to_8(fontPngPtr); } fontWidth_ = fontWidth / defaultFontWidth_; fontHeight_ = fontHeight >> 1; PNGReadRow(fontWidth_, fontHeight_, fontPngPtr, fontBuf_); - if (fp != nullptr) { - fclose(fp); - fp = nullptr; - } + CheckInitFont(fontPngPtr, fp, fontInfoPtr); } void TextLabel::SetText(const char *str) -- Gitee From 11025a2df07b5651a7f587f1007cfeb242c5c22f Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 15 Sep 2021 07:29:11 +0000 Subject: [PATCH 07/94] change UT framework Signed-off-by: ma_nan --- BUILD.gn | 22 +++++ ohos.build | 5 +- test/unittest/BUILD.gn | 84 ++++++++++--------- .../applypatch_test/all_cmd_unittest.cpp | 6 +- .../applypatch_test/applypatch_unittest.cpp | 6 +- .../applypatch_test/blockset_unittest.cpp | 11 +-- .../applypatch_test/bspatch_unittest.cpp | 3 +- .../applypatch_test/commands_unittest.cpp | 5 +- .../applypatch_test/imagepatch_unittest.cpp | 9 +- .../partition_update_record_unittest.cpp | 7 +- .../applypatch_test/store_unittest.cpp | 5 +- .../transfer_manager_unittest.cpp | 5 +- test/unittest/diffpatch/bzip2_unittest.cpp | 25 +++--- .../unittest/diffpatch/diffpatch_unittest.cpp | 43 +++++----- .../fs_manager/do_partition_unittest.cpp | 5 +- test/unittest/log_test/log_unittest.cpp | 6 +- .../misc_info_test/misc_info_unittest.cpp | 4 +- .../unittest/mount_test/fstabapi_unittest.cpp | 11 +-- test/unittest/mount_test/mount_unittest.cpp | 14 ++-- test/unittest/package/package_unittest.cpp | 51 +++++------ test/unittest/package/pkg_algo_unittest.cpp | 13 +-- .../unittest/package/pkg_manager_unittest.cpp | 25 +++--- .../unittest/package/pkg_package_unittest.cpp | 9 +- .../script/basic_instruction_unittest.cpp | 3 +- .../script/script_instruction_unittest.cpp | 3 +- .../script/script_interpreter_unittest.cpp | 13 +-- test/unittest/script/script_unittest.cpp | 3 +- test/unittest/script/threadpool_unittest.cpp | 5 +- .../update_image_block_test.cpp | 7 +- .../update_partitions_unittest.cpp | 5 +- .../update_processor_unittest.cpp | 5 +- .../updater_binary_unittest.cpp | 6 +- .../updater_main_unittest.cpp | 40 +++++++-- .../updater_test/updater_unittest.cpp | 7 +- .../updater_ui_test/updater_ui_unittest.cpp | 5 +- .../updaterkits_test/updaterkits_unittest.cpp | 4 +- test/unittest/utils/utils_unittest.cpp | 15 ++-- 37 files changed, 290 insertions(+), 205 deletions(-) create mode 100644 BUILD.gn diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 00000000..bb7209a4 --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +group("unittest") { + testonly = true + deps = [ + "test/unittest:updater_unittest" + ] +} + diff --git a/ohos.build b/ohos.build index 65c0a527..9ef224ed 100644 --- a/ohos.build +++ b/ohos.build @@ -28,7 +28,10 @@ "//base/update/updater/services/ui:libui", "//third_party/libdrm:libdrm", "//third_party/e2fsprogs:e2fsprogs" - ] + ], + "test_list": [ + "//base/update/updater:unittest" + ] } } } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index d1e94180..89a60a0e 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -11,7 +11,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/ohos.gni") +import("//build/test.gni") + +module_output_path = "updater/updater_test" config("utest_config") { visibility = [ ":*" ] @@ -27,43 +29,44 @@ config("utest_config") { ldflags = [ "--coverage" ] } -ohos_executable("updater_ut") { +ohos_unittest("updater_unittest") { + testonly = true + module_out_path = module_output_path sources = [ - "applypatch_test/all_cmd_unittest.cpp", - "applypatch_test/applypatch_unittest.cpp", - "applypatch_test/blockset_unittest.cpp", - "applypatch_test/bspatch_unittest.cpp", - "applypatch_test/commands_unittest.cpp", - "applypatch_test/imagepatch_unittest.cpp", - "applypatch_test/partition_update_record_unittest.cpp", - "applypatch_test/store_unittest.cpp", - "applypatch_test/transfer_manager_unittest.cpp", - "diffpatch/bzip2_unittest.cpp", - "diffpatch/diffpatch_unittest.cpp", - "fs_manager/do_partition_unittest.cpp", - "log_test/log_unittest.cpp", - "misc_info_test/misc_info_unittest.cpp", - "mount_test/fstabapi_unittest.cpp", - "mount_test/mount_unittest.cpp", - "package/package_unittest.cpp", - "package/pkg_algo_unittest.cpp", - "package/pkg_manager_unittest.cpp", - "package/pkg_package_unittest.cpp", - "script/basic_instruction_unittest.cpp", - "script/script_instruction_unittest.cpp", - "script/script_interpreter_unittest.cpp", - "script/script_unittest.cpp", - "script/threadpool_unittest.cpp", - "updater_binary/update_image_block_test.cpp", - "updater_binary/update_partitions_unittest.cpp", - "updater_binary/update_processor_unittest.cpp", - "updater_binary/updater_binary_unittest.cpp", - "updater_main_test/updater_main_unittest.cpp", + #"applypatch_test/all_cmd_unittest.cpp", + #"applypatch_test/applypatch_unittest.cpp", + #"applypatch_test/blockset_unittest.cpp", + #"applypatch_test/bspatch_unittest.cpp", + #"applypatch_test/commands_unittest.cpp", + #"applypatch_test/imagepatch_unittest.cpp", + #"applypatch_test/partition_update_record_unittest.cpp", + #"applypatch_test/store_unittest.cpp", + #"applypatch_test/transfer_manager_unittest.cpp", + #"diffpatch/bzip2_unittest.cpp", + #"diffpatch/diffpatch_unittest.cpp", + #"fs_manager/do_partition_unittest.cpp", + #"log_test/log_unittest.cpp", + #"misc_info_test/misc_info_unittest.cpp", + #"mount_test/fstabapi_unittest.cpp", + #"mount_test/mount_unittest.cpp", + #"package/package_unittest.cpp", + #"package/pkg_algo_unittest.cpp", + #"package/pkg_package_unittest.cpp", + #"package/pkg_manager_unittest.cpp", + #"script/basic_instruction_unittest.cpp", + #"script/script_instruction_unittest.cpp", + #"script/script_interpreter_unittest.cpp", + #"script/script_unittest.cpp", + #"script/threadpool_unittest.cpp", + #"updater_binary/update_image_block_test.cpp", + #"updater_binary/update_partitions_unittest.cpp", + #"updater_binary/update_processor_unittest.cpp", + #"updater_binary/updater_binary_unittest.cpp", + #"updater_main_test/updater_main_unittest.cpp", "updater_test/updater_unittest.cpp", - "updater_ui_test/updater_ui_unittest.cpp", - "updater_ut_entry.cpp", - "updaterkits_test/updaterkits_unittest.cpp", - "utils/utils_unittest.cpp", + #"updater_ui_test/updater_ui_unittest.cpp", + #"updaterkits_test/updaterkits_unittest.cpp", + #"utils/utils_unittest.cpp", ] sources += [ @@ -169,6 +172,7 @@ ohos_executable("updater_ut") { "//third_party/bzip2", "//third_party/libdrm/include/drm", "//third_party/libdrm", + "//third_party/googletest/googletest/include", "//drivers/framework/ability/sbuf/include", "//drivers/framework/include/platform", "//drivers/framework/include/core", @@ -194,8 +198,8 @@ ohos_executable("updater_ut") { "//third_party/bounds_checking_function:libsec_static", "//third_party/bzip2:libbz2", "//third_party/cJSON:cjson_static", - "//third_party/googletest:gmock", - "//third_party/googletest:gtest", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", "//third_party/lz4:liblz4_static", "//third_party/openssl:crypto_source", "//third_party/openssl:ssl_source", @@ -207,13 +211,13 @@ ohos_executable("updater_ut") { "//base/update/updater/test/unittest:test_update_binary_abnormal", ] + cflags_cc = [ "-fexceptions" ] + defines = [ "UPDATER_UT", "BUILD_OHOS", ] - cflags_cc = [ "-fexceptions" ] - public_configs = [ ":utest_config" ] install_enable = true part_name = "updater" diff --git a/test/unittest/applypatch_test/all_cmd_unittest.cpp b/test/unittest/applypatch_test/all_cmd_unittest.cpp index 62768b68..e020381d 100755 --- a/test/unittest/applypatch_test/all_cmd_unittest.cpp +++ b/test/unittest/applypatch_test/all_cmd_unittest.cpp @@ -24,6 +24,8 @@ #include "log/log.h" #include "utils.h" + +using namespace testing::ext; using namespace updater; using namespace std; namespace updater_ut { @@ -96,7 +98,7 @@ bool AllCmdUnitTest::WriteTestBin(int fd, const uint8_t &data, size_t size) cons // new command is not easy to simulate, it depends on // compression and other condition. // Leave new command to be covered by update_image_block test. -TEST_F(AllCmdUnitTest, allCmd_test_001) +HWTEST_F(AllCmdUnitTest, allCmd_test_001,TestSize.Level1) { TransferManager *tm = TransferManager::GetTransferManagerInstance(); // Read source @@ -162,7 +164,7 @@ int AllCmdUnitTest::AllCmdUnitTestMove(int &fd, std::vector &allCmd return 0; } -TEST_F(AllCmdUnitTest, allCmd_test_002) +HWTEST_F(AllCmdUnitTest, allCmd_test_002,TestSize.Level1) { TransferManagerPtr tm = TransferManager::GetTransferManagerInstance(); std::string filePath = "/tmp/test.bin"; diff --git a/test/unittest/applypatch_test/applypatch_unittest.cpp b/test/unittest/applypatch_test/applypatch_unittest.cpp index f86307b7..6cc31833 100755 --- a/test/unittest/applypatch_test/applypatch_unittest.cpp +++ b/test/unittest/applypatch_test/applypatch_unittest.cpp @@ -63,7 +63,7 @@ void ApplyPatchUnitTest::TearDown() unlink(devPath.c_str()); } -TEST_F(ApplyPatchUnitTest, updater_RawWriter) +HWTEST_F(ApplyPatchUnitTest, updater_RawWriter, TestSize.Level1) { WriteMode mode = WRITE_RAW; uint8_t *addr = nullptr; @@ -103,7 +103,7 @@ TEST_F(ApplyPatchUnitTest, updater_RawWriter) DataWriter::ReleaseDataWriter(writer); } -TEST_F(ApplyPatchUnitTest, updater_DataWriterOpenPartition) +HWTEST_F(ApplyPatchUnitTest, updater_DataWriterOpenPartition, TestSize.Level1) { WriteMode mode = WRITE_RAW; std::string partitionName = ""; @@ -124,7 +124,7 @@ TEST_F(ApplyPatchUnitTest, updater_DataWriterOpenPartition) DataWriter::ReleaseDataWriter(writer); } -TEST_F(ApplyPatchUnitTest, updater_CreateDataWriter) +HWTEST_F(ApplyPatchUnitTest, updater_CreateDataWriter, TestSize.Level1) { std::vector modes = { WRITE_RAW, WRITE_DECRYPT }; std::unique_ptr writer = nullptr; diff --git a/test/unittest/applypatch_test/blockset_unittest.cpp b/test/unittest/applypatch_test/blockset_unittest.cpp index e1b590db..2af400b2 100755 --- a/test/unittest/applypatch_test/blockset_unittest.cpp +++ b/test/unittest/applypatch_test/blockset_unittest.cpp @@ -23,6 +23,7 @@ #include "applypatch/command.h" #include "log/log.h" +using namespace testing::ext; using namespace updater_ut; using namespace updater; using namespace std; @@ -38,7 +39,7 @@ void BlockSetUnitTest::TearDown(void) cout << "TearDownTestCase" << endl; } -TEST(BlockSetUnitTest, blockset_test_001) +HWTEST_F(BlockSetUnitTest, blockset_test_001,TestSize.Level1) { cout << "Blockset ut start"; BlockSet block(std::vector {BlockPair{0, 1}}); @@ -65,7 +66,7 @@ TEST(BlockSetUnitTest, blockset_test_001) EXPECT_EQ(ret, -1); } -TEST(BlockSetUnitTest, blockset_test_002) +HWTEST_F(BlockSetUnitTest, blockset_test_002,TestSize.Level1) { cout << "Blockset ut two blocks overlap"; BlockSet block(std::vector {BlockPair{0, 1}}); @@ -77,7 +78,7 @@ TEST(BlockSetUnitTest, blockset_test_002) EXPECT_EQ(ret, false); } -TEST(BlockSetUnitTest, blockset_test_003) +HWTEST_F(BlockSetUnitTest, blockset_test_003,TestSize.Level1) { cout << "Blockset ut two blocks overlap"; std::vector buffer; @@ -89,7 +90,7 @@ TEST(BlockSetUnitTest, blockset_test_003) blk.WriteDataToBlock(fd, buffer); } -TEST(BlockSetUnitTest, blockset_test_004) +HWTEST_F(BlockSetUnitTest, blockset_test_004,TestSize.Level1) { cout << "Blockset ut two blocks overlap"; std::vector srcBuffer; @@ -102,7 +103,7 @@ TEST(BlockSetUnitTest, blockset_test_004) BlockSet::MoveBlock(srcBuffer, blk, tgtBuffer); } -TEST(BlockSetUnitTest, blockset_test_005) +HWTEST_F(BlockSetUnitTest, blockset_test_005,TestSize.Level1) { std::string hashValue = "5aa246ebe8e817740f12cc0f6e536c5ea22e5db177563a1caea5a86614275546"; std::string blockInfo = "2,20755,21031 276 2,20306,20582"; diff --git a/test/unittest/applypatch_test/bspatch_unittest.cpp b/test/unittest/applypatch_test/bspatch_unittest.cpp index 4a52f87f..747f813f 100755 --- a/test/unittest/applypatch_test/bspatch_unittest.cpp +++ b/test/unittest/applypatch_test/bspatch_unittest.cpp @@ -21,6 +21,7 @@ #include "applypatch/transfer_manager.h" #include "log/log.h" +using namespace testing::ext; using namespace updater; using namespace std; @@ -48,7 +49,7 @@ void BspatchUnitTest::TearDown() cout << "Updater Unit BspatchUnitTest End!" << endl; } -TEST_F(BspatchUnitTest, bspatch_test_001) +HWTEST_F(BspatchUnitTest, bspatch_test_001, TestSize.Level1) { std::string partitionName; std::string transferName; diff --git a/test/unittest/applypatch_test/commands_unittest.cpp b/test/unittest/applypatch_test/commands_unittest.cpp index 4ff2578c..b871fe63 100755 --- a/test/unittest/applypatch_test/commands_unittest.cpp +++ b/test/unittest/applypatch_test/commands_unittest.cpp @@ -21,6 +21,7 @@ #include "applypatch/command.h" #include "log/log.h" +using namespace testing::ext; using namespace updater; using namespace std; @@ -48,7 +49,7 @@ void CommandsUnitTest::TearDown() cout << "Updater Unit CommandsUnitTest End!" << endl; } -TEST_F(CommandsUnitTest, command_test_001) +HWTEST_F(CommandsUnitTest, command_test_001, TestSize.Level0) { std::string hashValue = "5aa246ebe8e817740f12cc0f6e536c5ea22e5db177563a1caea5a86614275546"; std::string blockInfo = "2,20755,21031 276 2,20306,20582"; @@ -63,7 +64,7 @@ TEST_F(CommandsUnitTest, command_test_001) EXPECT_EQ(cmd->GetCommandLine(), cmdLine); } -TEST_F(CommandsUnitTest, command_test_002) +HWTEST_F(CommandsUnitTest, command_test_002,TestSize.Level0) { std::string hashValue = "5aa246ebe8e817740f12cc0f6e536c5ea22e5db177563a1caea5a86614275546"; std::string blockInfo = "2,20755,21031 276 2,20306,20582"; diff --git a/test/unittest/applypatch_test/imagepatch_unittest.cpp b/test/unittest/applypatch_test/imagepatch_unittest.cpp index 361b37fd..4316dfee 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.cpp +++ b/test/unittest/applypatch_test/imagepatch_unittest.cpp @@ -30,6 +30,7 @@ #include "pkg_utils.h" #include "utils.h" +using namespace testing::ext; using namespace updater; namespace updater_ut { bool ImagePatchTest::ReadContentFromFile(const std::string& file, std::string &content) const @@ -126,25 +127,25 @@ int ImagePatchTest::TestLZ4ModeImagePatch() const return 0; } -TEST_F(ImagePatchTest, TestZipModeImagePatch) +HWTEST_F(ImagePatchTest, TestZipModeImagePatch, TestSize.Level1) { ImagePatchTest test; EXPECT_EQ(0, test.TestZipModeImagePatch()); } -TEST_F(ImagePatchTest, TestGZipModeImagePatch) +HWTEST_F(ImagePatchTest, TestGZipModeImagePatch, TestSize.Level1) { ImagePatchTest test; EXPECT_EQ(0, test.TestGZipModeImagePatch()); } -TEST_F(ImagePatchTest, TestLZ4ModeImagePatch) +HWTEST_F(ImagePatchTest, TestLZ4ModeImagePatch, TestSize.Level1) { ImagePatchTest test; EXPECT_EQ(0, test.TestLZ4ModeImagePatch()); } -TEST_F(ImagePatchTest, TestNormalModeImagePatch) +HWTEST_F(ImagePatchTest, TestNormalModeImagePatch, TestSize.Level1) { ImagePatchTest test; EXPECT_EQ(0, test.TestNormalModeImagePatch()); diff --git a/test/unittest/applypatch_test/partition_update_record_unittest.cpp b/test/unittest/applypatch_test/partition_update_record_unittest.cpp index c24d16df..14193d60 100755 --- a/test/unittest/applypatch_test/partition_update_record_unittest.cpp +++ b/test/unittest/applypatch_test/partition_update_record_unittest.cpp @@ -25,6 +25,7 @@ #include "package/pkg_manager.h" #include "updater/updater.h" +using namespace testing::ext; using namespace updater; using namespace std; namespace updater_ut { @@ -51,7 +52,7 @@ void PartitionUpdateRecordUnitTest::TearDown() PartitionRecord::GetInstance().ClearRecordPartitionOffset(); } -TEST_F(PartitionUpdateRecordUnitTest, partition_record_test_001) +HWTEST_F(PartitionUpdateRecordUnitTest, partition_record_test_001, TestSize.Level1) { const std::string partitionName = "ut_partition"; bool ret = PartitionRecord::GetInstance().RecordPartitionUpdateStatus(partitionName, true); @@ -61,14 +62,14 @@ TEST_F(PartitionUpdateRecordUnitTest, partition_record_test_001) EXPECT_EQ(ret, true); } -TEST_F(PartitionUpdateRecordUnitTest, partition_record_test_002) +HWTEST_F(PartitionUpdateRecordUnitTest, partition_record_test_002, TestSize.Level1) { const std::string partitionName = "ut_partition1"; bool ret = PartitionRecord::GetInstance().IsPartitionUpdated(partitionName); EXPECT_EQ(ret, false); } -TEST_F(PartitionUpdateRecordUnitTest, partition_record_test_003) +HWTEST_F(PartitionUpdateRecordUnitTest, partition_record_test_003, TestSize.Level1) { string partitionName = "partitionName"; for (int i = 0; i < MAX_PARTITION_NUM; i++) { diff --git a/test/unittest/applypatch_test/store_unittest.cpp b/test/unittest/applypatch_test/store_unittest.cpp index 263051a7..8f683f94 100755 --- a/test/unittest/applypatch_test/store_unittest.cpp +++ b/test/unittest/applypatch_test/store_unittest.cpp @@ -23,6 +23,7 @@ #include "log/log.h" #include "utils.h" +using namespace testing::ext; using namespace updater_ut; using namespace updater; using namespace std; @@ -38,7 +39,7 @@ void StoreUnitTest::TearDown() cout << "TearDownTestCase" << endl; } -TEST(StoreUnitTest, store_test_001) +HWTEST_F(StoreUnitTest, store_test_001, TestSize.Level1) { std::string storePath = "/data/updater/ut_test"; Store::CreateNewSpace(storePath, true); @@ -55,7 +56,7 @@ TEST(StoreUnitTest, store_test_001) EXPECT_EQ(Store::CreateNewSpace(storePath, true), 0); } -TEST(StoreUnitTest, store_test_002) +HWTEST_F(StoreUnitTest, store_test_002, TestSize.Level1) { std::string storePath = "/data/updater/ut_test"; Store::CreateNewSpace(storePath, true); diff --git a/test/unittest/applypatch_test/transfer_manager_unittest.cpp b/test/unittest/applypatch_test/transfer_manager_unittest.cpp index 7f64800d..1e90f090 100755 --- a/test/unittest/applypatch_test/transfer_manager_unittest.cpp +++ b/test/unittest/applypatch_test/transfer_manager_unittest.cpp @@ -21,6 +21,7 @@ #include "applypatch/transfer_manager.h" #include "log/log.h" +using namespace testing::ext; using namespace updater; using namespace std; namespace updater_ut { @@ -47,7 +48,7 @@ void TransferManagerUnitTest::TearDown() cout << "Updater Unit TransferManagerUnitTest End!" << endl; } -TEST_F(TransferManagerUnitTest, transfer_manager_test_001) +HWTEST_F(TransferManagerUnitTest, transfer_manager_test_001, TestSize.Level1) { TransferManagerPtr tm = TransferManager::GetTransferManagerInstance(); std::string cmd = "zero 2,0,1"; @@ -55,7 +56,7 @@ TEST_F(TransferManagerUnitTest, transfer_manager_test_001) TransferManager::ReleaseTransferManagerInstance(tm); } -TEST_F(TransferManagerUnitTest, transfer_manager_test_002) +HWTEST_F(TransferManagerUnitTest, transfer_manager_test_002, TestSize.Level1) { TransferManagerPtr tm = TransferManager::GetTransferManagerInstance(); tm->ReloadForRetry(); diff --git a/test/unittest/diffpatch/bzip2_unittest.cpp b/test/unittest/diffpatch/bzip2_unittest.cpp index d80b1fa1..9c367c42 100755 --- a/test/unittest/diffpatch/bzip2_unittest.cpp +++ b/test/unittest/diffpatch/bzip2_unittest.cpp @@ -24,6 +24,7 @@ using namespace std; using namespace hpackage; using namespace updatepatch; +using namespace testing::ext; namespace { #define LZ4_BLOCK_SIZE(blockId) (1 << (8 + (2 * (blockId)))) @@ -250,19 +251,19 @@ public: } }; -TEST_F(BZip2AdapterUnitTest, BZip2AdapterBufferTest) +HWTEST_F(BZip2AdapterUnitTest, BZip2AdapterBufferTest, TestSize.Level1) { BZip2AdapterUnitTest test; EXPECT_EQ(0, test.BZip2AdapterBufferTest()); } -TEST_F(BZip2AdapterUnitTest, BZip2AdapterAddMoreTest) +HWTEST_F(BZip2AdapterUnitTest, BZip2AdapterAddMoreTest, TestSize.Level1) { BZip2AdapterUnitTest test; EXPECT_EQ(0, test.BZip2AdapterAddMoreTest()); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForZip) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForZip, TestSize.Level1) { ZipFileInfo zipInfo {}; zipInfo.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP; @@ -275,7 +276,7 @@ TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForZip) EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.new", &zipInfo.fileInfo)); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; @@ -287,7 +288,7 @@ TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4) EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_2) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_2, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; @@ -299,7 +300,7 @@ TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_2) EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_3) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_3, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; @@ -311,7 +312,7 @@ TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_3) EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_4) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_4, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; @@ -323,7 +324,7 @@ TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_4) EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_5) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_5, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; @@ -336,7 +337,7 @@ TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4_5) EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK; @@ -348,7 +349,7 @@ TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block) EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_2) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_2, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK; @@ -360,7 +361,7 @@ TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_2) EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_3) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_3, TestSize.Level1) { Lz4FileInfo lz4Info {}; lz4Info.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK; @@ -372,7 +373,7 @@ TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_3) EXPECT_EQ(0, test.DeflateAdapterTest("../diffpatch/patchtest.test", &lz4Info.fileInfo)); } -TEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_4) +HWTEST_F(BZip2AdapterUnitTest, DeflateAdapterTestForLz4Block_4, TestSize.Level1) { DeflateAdapter adapterTest; BlockBuffer srcTestData; diff --git a/test/unittest/diffpatch/diffpatch_unittest.cpp b/test/unittest/diffpatch/diffpatch_unittest.cpp index d6a18f2a..9292e18f 100755 --- a/test/unittest/diffpatch/diffpatch_unittest.cpp +++ b/test/unittest/diffpatch/diffpatch_unittest.cpp @@ -22,6 +22,7 @@ using namespace std; using namespace hpackage; using namespace updatepatch; +using namespace testing::ext; namespace { class DiffPatchUnitTest : public testing::Test { @@ -179,7 +180,7 @@ public: } }; -TEST_F(DiffPatchUnitTest, BlockDiffPatchTest) +HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.BlockDiffPatchTest( @@ -189,7 +190,7 @@ TEST_F(DiffPatchUnitTest, BlockDiffPatchTest) "../diffpatch/patchtest.new_1")); } -TEST_F(DiffPatchUnitTest, ImgageDiffPatchFileTest) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchFileTest, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -199,7 +200,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchFileTest) "../diffpatch/patchtest.new_2")); } -TEST_F(DiffPatchUnitTest, ImgageDiffPatchFileWithLimit) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchFileWithLimit, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(16, @@ -209,7 +210,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchFileWithLimit) "../diffpatch/patchtest.new_3")); } -TEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -219,7 +220,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile) "../diffpatch/PatchGztest_gz_new.zip")); } -TEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -229,7 +230,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File) "../diffpatch/PatchLz4test_lz4_new.lz")); } -TEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_1) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_1, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -239,7 +240,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_1) "../diffpatch/ImgageDiffPatchLz4File_1_lz4_new.lz")); } -TEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_2) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_2, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(1, @@ -249,7 +250,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_2) "../diffpatch/ImgageDiffPatchLz4File_1_lz4_new.lz")); } -TEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_3) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_3, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -260,7 +261,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchLz4File_3) } // 测试包含一个文件时,新增一个文件 -TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -271,7 +272,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile) } // 测试使用winrar的压缩文件 -TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_1) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_1, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -282,7 +283,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_1) } // 测试包含一个文件时,文件内容不相同 -TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_2) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_2, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -293,7 +294,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_2) } // linux 上压缩,多文件测试 -TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_3) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_3, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -304,7 +305,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_3) } // linux 上压缩,超大buffer length测试 -TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_4) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_4, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest(0, @@ -314,7 +315,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchZipFile_4) "../diffpatch/ImgageDiffPatchZipFile_4_zip_new.zip")); } -TEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile2) +HWTEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile2, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.ImgageDiffPatchFileTest2(0, @@ -324,7 +325,7 @@ TEST_F(DiffPatchUnitTest, ImgageDiffPatchGzFile2) "../diffpatch/PatchGztest_gz_new.zip")); } -TEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile) +HWTEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.BlockDiffPatchTest2( @@ -334,7 +335,7 @@ TEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile) "../diffpatch/PatchGztest_gz_new.zip", true)); } -TEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile_1) +HWTEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile_1, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.BlockDiffPatchTest2( @@ -344,7 +345,7 @@ TEST_F(DiffPatchUnitTest, BlockDiffPatchGzFile_1) "../diffpatch/PatchGztest_gz_new.zip", false)); } -TEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File) +HWTEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.BlockDiffPatchTest2( @@ -354,7 +355,7 @@ TEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File) "../diffpatch/PatchLz4test_lz4_new.lz", true)); } -TEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File_1) +HWTEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File_1, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.BlockDiffPatchTest2( @@ -364,7 +365,7 @@ TEST_F(DiffPatchUnitTest, BlockDiffPatchLz4File_1) "../diffpatch/PatchLz4test_lz4_new.lz", false)); } -TEST_F(DiffPatchUnitTest, BlockDiffPatchTest_0) +HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest_0, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.BlockDiffPatchTest2( @@ -374,7 +375,7 @@ TEST_F(DiffPatchUnitTest, BlockDiffPatchTest_0) "../diffpatch/patchtest.new_2", true)); } -TEST_F(DiffPatchUnitTest, BlockDiffPatchTest_1) +HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest_1, TestSize.Level1) { DiffPatchUnitTest test; EXPECT_EQ(0, test.BlockDiffPatchTest2( @@ -384,7 +385,7 @@ TEST_F(DiffPatchUnitTest, BlockDiffPatchTest_1) "../diffpatch/patchtest.new_2", false)); } -TEST_F(DiffPatchUnitTest, BlockDiffPatchTest_2) +HWTEST_F(DiffPatchUnitTest, BlockDiffPatchTest_2, TestSize.Level1) { std::vector testDate; testDate.push_back('a'); diff --git a/test/unittest/fs_manager/do_partition_unittest.cpp b/test/unittest/fs_manager/do_partition_unittest.cpp index 939b2d8a..d7cd7998 100755 --- a/test/unittest/fs_manager/do_partition_unittest.cpp +++ b/test/unittest/fs_manager/do_partition_unittest.cpp @@ -25,7 +25,8 @@ #include "partitions.h" #include "securec.h" -using namespace updater; +using namespace updater; +using namespace testing::ext; using namespace std; namespace updater_ut { @@ -74,7 +75,7 @@ static void InitEmmcPartition(struct Partition &part, const std::string &partNam part.fsType = "emmc"; } -TEST_F(DoPartitionUnitTest, do_partition_test_001) +HWTEST_F(DoPartitionUnitTest, do_partition_test_001, TestSize.Level1) { PartitonList nList; int partitionIndex = 0; diff --git a/test/unittest/log_test/log_unittest.cpp b/test/unittest/log_test/log_unittest.cpp index e78a0a6a..8989569e 100755 --- a/test/unittest/log_test/log_unittest.cpp +++ b/test/unittest/log_test/log_unittest.cpp @@ -20,7 +20,7 @@ using namespace testing::ext; using namespace updater_ut; -using namespace updater; +using namespace updater; using namespace std; namespace updater_ut { @@ -34,7 +34,7 @@ void LogUnitTest::TearDownTestCase(void) cout << "TearDownTestCase" << endl; } -TEST(LogUnitTest, log_test_001) +HWTEST_F(LogUnitTest, log_test_001, TestSize.Level1) { SetLogLevel(ERROR); LOG(ERROR) << "this is ut"; @@ -62,7 +62,7 @@ TEST(LogUnitTest, log_test_001) } } -TEST(LogUnitTest, log_test_002) +HWTEST_F(LogUnitTest, log_test_002, TestSize.Level0) { InitUpdaterLogger("UPDATER_UT", "", "", ""); SetLogLevel(ERROR); diff --git a/test/unittest/misc_info_test/misc_info_unittest.cpp b/test/unittest/misc_info_test/misc_info_unittest.cpp index 2dc4cec7..dd3b1545 100755 --- a/test/unittest/misc_info_test/misc_info_unittest.cpp +++ b/test/unittest/misc_info_test/misc_info_unittest.cpp @@ -21,7 +21,7 @@ using namespace testing::ext; using namespace updater_ut; -using namespace updater; +using namespace updater; using namespace std; namespace updater_ut { @@ -37,7 +37,7 @@ void MiscInfoUnitTest::TearDownTestCase(void) cout << "Updater Unit MiscInfoUnitTest End!" << endl; } -TEST(MiscInfoUnitTest, misc_info_test_001) +HWTEST_F(MiscInfoUnitTest, misc_info_test_001, TestSize.Level1) { auto fp = std::unique_ptr(fopen(MISC_FILE.c_str(), "wb"), fclose); EXPECT_NE(fp, nullptr); diff --git a/test/unittest/mount_test/fstabapi_unittest.cpp b/test/unittest/mount_test/fstabapi_unittest.cpp index 332e5b09..8dda18c9 100755 --- a/test/unittest/mount_test/fstabapi_unittest.cpp +++ b/test/unittest/mount_test/fstabapi_unittest.cpp @@ -52,7 +52,7 @@ void FstabApiUnitTest::SetUpTestCase(void) {} // do something at the each function end void FstabApiUnitTest::TearDownTestCase(void) {} -TEST_F(FstabApiUnitTest, ReadFstabFromFile_unitest) +HWTEST_F(FstabApiUnitTest, ReadFstabFromFile_unitest, TestSize.Level1) { Fstab fstab; const std::string fstabFile1 = "/data/fstab.updater1"; @@ -75,7 +75,7 @@ TEST_F(FstabApiUnitTest, ReadFstabFromFile_unitest) EXPECT_TRUE(ret); } -TEST_F(FstabApiUnitTest, FindFstabItemForPath_unitest) +HWTEST_F(FstabApiUnitTest, FindFstabItemForPath_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/FindFstabItemForPath1.fstable"; Fstab fstab1; @@ -103,7 +103,7 @@ TEST_F(FstabApiUnitTest, FindFstabItemForPath_unitest) } } -TEST_F(FstabApiUnitTest, FindFstabItemForMountPoint_unitest) +HWTEST_F(FstabApiUnitTest, FindFstabItemForMountPoint_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/FindFstabItemForMountPoint1.fstable"; Fstab fstab1; @@ -121,8 +121,8 @@ TEST_F(FstabApiUnitTest, FindFstabItemForMountPoint_unitest) SUCCEED(); } } - -TEST_F(FstabApiUnitTest, GetMountFlags_unitest) +/* +HWTEST_F(FstabApiUnitTest, GetMountFlags_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/GetMountFlags1.fstable"; Fstab fstab1; @@ -137,4 +137,5 @@ TEST_F(FstabApiUnitTest, GetMountFlags_unitest) unsigned long flags = GetMountFlags(item->mountOptions, fsSpecificOptions); EXPECT_EQ(flags, static_cast(MS_NOSUID | MS_NODEV | MS_NOATIME)); } +*/ } // namespace updater_ut diff --git a/test/unittest/mount_test/mount_unittest.cpp b/test/unittest/mount_test/mount_unittest.cpp index 04df3a6b..832a936d 100755 --- a/test/unittest/mount_test/mount_unittest.cpp +++ b/test/unittest/mount_test/mount_unittest.cpp @@ -60,7 +60,7 @@ void MountUnitTest::TearDownTestCase(void) rmdir("/misc"); } -TEST_F(MountUnitTest, FormatPartition_unitest) +HWTEST_F(MountUnitTest, FormatPartition_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/FormatPartition1.fstable"; LoadSpecificFstab(fstabFile1); @@ -78,7 +78,7 @@ TEST_F(MountUnitTest, FormatPartition_unitest) EXPECT_EQ(ret, -1); } -TEST_F(MountUnitTest, MountForPath_unitest) +HWTEST_F(MountUnitTest, MountForPath_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/MountForPath1.fstable"; LoadSpecificFstab(fstabFile1); @@ -99,7 +99,7 @@ TEST_F(MountUnitTest, MountForPath_unitest) EXPECT_EQ(ret, -1); } -TEST_F(MountUnitTest, UmountForPath_unitest) +HWTEST_F(MountUnitTest, UmountForPath_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/UmountForPath1.fstable"; LoadSpecificFstab(fstabFile1); @@ -114,7 +114,7 @@ TEST_F(MountUnitTest, UmountForPath_unitest) EXPECT_EQ(ret, 0); } -TEST_F(MountUnitTest, GetMountStatusForPath_unitest) +HWTEST_F(MountUnitTest, GetMountStatusForPath_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/GetMountStatusForPath1.fstable"; LoadSpecificFstab(fstabFile1); @@ -129,7 +129,7 @@ TEST_F(MountUnitTest, GetMountStatusForPath_unitest) EXPECT_EQ(ret, MountStatus::MOUNT_UMOUNTED); } -TEST_F(MountUnitTest, GetItemForMountPoint_unitest) +HWTEST_F(MountUnitTest, GetItemForMountPoint_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/GetItemForMountPoint1.fstable"; LoadSpecificFstab(fstabFile1); @@ -152,7 +152,7 @@ TEST_F(MountUnitTest, GetItemForMountPoint_unitest) } } -TEST_F(MountUnitTest, SetupPartitions_unitest) +HWTEST_F(MountUnitTest, SetupPartitions_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/SetupPartitions1.fstable"; LoadSpecificFstab(fstabFile1); @@ -164,7 +164,7 @@ TEST_F(MountUnitTest, SetupPartitions_unitest) EXPECT_EQ(ret, 0); } -TEST_F(MountUnitTest, GetBlockDeviceByMountPoint_unitest) +HWTEST_F(MountUnitTest, GetBlockDeviceByMountPoint_unitest, TestSize.Level1) { LoadFstab(); const std::string fstabFile1 = "/data/updater/mount_unitest/GetBlockDeviceByMountPoint1.fstable"; diff --git a/test/unittest/package/package_unittest.cpp b/test/unittest/package/package_unittest.cpp index c1d91fba..381c58f6 100755 --- a/test/unittest/package/package_unittest.cpp +++ b/test/unittest/package/package_unittest.cpp @@ -30,6 +30,7 @@ using namespace std; using namespace hpackage; using namespace updater; +using namespace testing::ext; namespace { class PackageUnitTest : public PkgTest { @@ -219,7 +220,7 @@ public: return ret; } - int TestVersifyUpgradePackage() + int TestVerifyUpgradePackage() { int ret = TestPackagePack(); constexpr size_t digestSize = 32; @@ -236,9 +237,9 @@ public: return 0; } - int TestVersifyZipWithCallback() + int TestVerifyZipWithCallback() { - int32_t ret = TestVersifyZip(); + int32_t ret = TestVerifyZip(); EXPECT_EQ(ret, 0); std::string path = GetCurrPath(); path = TEST_PATH_TO + testZipPackageName; @@ -248,7 +249,7 @@ public: return 0; } - int TestVersifyZip() + int TestVerifyZip() { int32_t ret = TestZipPkgCompress(); EXPECT_EQ(ret, 0); @@ -267,7 +268,7 @@ public: return 0; } - int TestVersifyLz4() + int TestVerifyLz4() { int32_t ret = TestLz4PkgCompress(); EXPECT_EQ(ret, 0); @@ -559,101 +560,101 @@ public: } }; -TEST_F(PackageUnitTest, TestPackage) +HWTEST_F(PackageUnitTest, TestPackage, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestPackagePack()); EXPECT_EQ(0, test.TestPackageUnpack()); } -TEST_F(PackageUnitTest, TestZipPackage) +HWTEST_F(PackageUnitTest, TestZipPackage, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestZipPkgCompress()); EXPECT_EQ(0, test.TestZipPkgDecompress()); } -TEST_F(PackageUnitTest, TestLz4Package) +HWTEST_F(PackageUnitTest, TestLz4Package, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestLz4PkgCompress()); EXPECT_EQ(0, test.TestLz4PkgDecompress()); } -TEST_F(PackageUnitTest, TestLz4PackageBlock) +HWTEST_F(PackageUnitTest, TestLz4PackageBlock, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestLz4PkgCompressBlock()); EXPECT_EQ(0, test.TestLz4PkgDecompress()); } -TEST_F(PackageUnitTest, TestCombinePkg) +HWTEST_F(PackageUnitTest, TestCombinePkg, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestCombinePkgUnpack()); } -TEST_F(PackageUnitTest, TestVersifyUpgradePackage) +HWTEST_F(PackageUnitTest, TestVerifyUpgradePackage, TestSize.Level1) { PackageUnitTest test; - EXPECT_EQ(0, test.TestVersifyUpgradePackage()); + EXPECT_EQ(0, test.TestVerifyUpgradePackage()); } -TEST_F(PackageUnitTest, TestVersifyZipWithCallback) +HWTEST_F(PackageUnitTest, TestVerifyZipWithCallback, TestSize.Level1) { PackageUnitTest test; - EXPECT_EQ(0, test.TestVersifyZipWithCallback()); + EXPECT_EQ(0, test.TestVerifyZipWithCallback()); } -TEST_F(PackageUnitTest, TestVersifyZip) +HWTEST_F(PackageUnitTest, TestVerifyZip, TestSize.Level1) { PackageUnitTest test; - EXPECT_EQ(0, test.TestVersifyZip()); + EXPECT_EQ(0, test.TestVerifyZip()); } -TEST_F(PackageUnitTest, TestVersifyLz4) { +HWTEST_F(PackageUnitTest, TestVerifyLz4, TestSize.Level1) { PackageUnitTest test; - EXPECT_EQ(0, test.TestVersifyLz4()); + EXPECT_EQ(0, test.TestVerifyLz4()); } -TEST_F(PackageUnitTest, TestInterfaceLz4) +HWTEST_F(PackageUnitTest, TestInterfaceLz4, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestInterfaceLz4()); } -TEST_F(PackageUnitTest, TestInterfaceZip) +HWTEST_F(PackageUnitTest, TestInterfaceZip, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestInterfaceZip()); } -TEST_F(PackageUnitTest, TestInvalidCreatePackage) +HWTEST_F(PackageUnitTest, TestInvalidCreatePackage, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestInvalidCreatePackage()); } -TEST_F(PackageUnitTest, TestGZipPkg) +HWTEST_F(PackageUnitTest, TestGZipPkg, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestGZipPkgCompress()); EXPECT_EQ(0, test.TestGZipPkgDecompressAll()); } -TEST_F(PackageUnitTest, TestSecondLoadPackage) +HWTEST_F(PackageUnitTest, TestSecondLoadPackage, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestSecondLoadPackage()); } -TEST_F(PackageUnitTest, TestL1PackagePack) +HWTEST_F(PackageUnitTest, TestL1PackagePack, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestL1PackagePack()); } -TEST_F(PackageUnitTest, TestL1PackagePackSha384) +HWTEST_F(PackageUnitTest, TestL1PackagePackSha384, TestSize.Level1) { PackageUnitTest test; EXPECT_EQ(0, test.TestL1PackagePackSha384()); diff --git a/test/unittest/package/pkg_algo_unittest.cpp b/test/unittest/package/pkg_algo_unittest.cpp index ba5a86f4..e78461bb 100755 --- a/test/unittest/package/pkg_algo_unittest.cpp +++ b/test/unittest/package/pkg_algo_unittest.cpp @@ -28,6 +28,7 @@ using namespace std; using namespace hpackage; using namespace updater; +using namespace testing::ext; namespace { constexpr size_t BUFFER_LEN = 10; @@ -217,7 +218,7 @@ private: }; }; -TEST_F(PkgAlgoUnitTest, TestHash256Digest) +HWTEST_F(PkgAlgoUnitTest, TestHash256Digest, TestSize.Level1) { PkgAlgoUnitTest test; EXPECT_EQ(0, test.TestCrcDigest()); @@ -225,31 +226,31 @@ TEST_F(PkgAlgoUnitTest, TestHash256Digest) EXPECT_EQ(0, test.TestHash384Digest()); } -TEST_F(PkgAlgoUnitTest, TestRsaSignVerify) +HWTEST_F(PkgAlgoUnitTest, TestRsaSignVerify, TestSize.Level1) { PkgAlgoUnitTest test; EXPECT_EQ(0, test.TestSignVerify(PKG_SIGN_METHOD_RSA, "rsa_private_key2048.pem", "signing_cert.crt")); } -TEST_F(PkgAlgoUnitTest, TestEccSignVerify) +HWTEST_F(PkgAlgoUnitTest, TestEccSignVerify, TestSize.Level1) { PkgAlgoUnitTest test; EXPECT_EQ(0, test.TestSignVerify(PKG_SIGN_METHOD_ECDSA, "ecc/prime256v1-key.pem", "ecc/signing_cert.crt")); } -TEST_F(PkgAlgoUnitTest, TestEccUserPackage) +HWTEST_F(PkgAlgoUnitTest, TestEccUserPackage, TestSize.Level1) { PkgAlgoUnitTest test; EXPECT_EQ(0, test.TestEccUserPackage(PKG_SIGN_METHOD_ECDSA, "ecc/prime256v1-key.pem", "ecc/signing_cert.crt")); } -TEST_F(PkgAlgoUnitTest, TestInvalid) +HWTEST_F(PkgAlgoUnitTest, TestInvalid, TestSize.Level1) { PkgAlgoUnitTest test; EXPECT_EQ(0, test.TestInvalidParam()); } -TEST_F(PkgAlgoUnitTest, TestPkgAlgoDeflate) +HWTEST_F(PkgAlgoUnitTest, TestPkgAlgoDeflate, TestSize.Level1) { ZipFileInfo info; PkgAlgoDeflate a1(info); diff --git a/test/unittest/package/pkg_manager_unittest.cpp b/test/unittest/package/pkg_manager_unittest.cpp index 2f68ebe9..5c4c578f 100755 --- a/test/unittest/package/pkg_manager_unittest.cpp +++ b/test/unittest/package/pkg_manager_unittest.cpp @@ -34,6 +34,7 @@ using namespace std; using namespace hpackage; using namespace updater; +using namespace testing::ext; namespace { constexpr auto WINDOWBITS = -15; // 32kb window; negative to indicate a raw stream. @@ -695,7 +696,7 @@ public: } }; -TEST_F(PkgMangerTest, TestGZipBuffer) +HWTEST_F(PkgMangerTest, TestGZipBuffer, TestSize.Level1) { PkgMangerTest test; hpackage::ZipFileInfo zipInfo; @@ -714,7 +715,7 @@ TEST_F(PkgMangerTest, TestGZipBuffer) uncompressedData.clear(); } -TEST_F(PkgMangerTest, TestLz4Buffer) +HWTEST_F(PkgMangerTest, TestLz4Buffer, TestSize.Level1) { PkgMangerTest test; hpackage::Lz4FileInfo lz4Info; @@ -734,7 +735,7 @@ TEST_F(PkgMangerTest, TestLz4Buffer) uncompressedData.clear(); } -TEST_F(PkgMangerTest, TestInvalidCreatePackage) +HWTEST_F(PkgMangerTest, TestInvalidCreatePackage, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestPackagePack()); @@ -742,49 +743,49 @@ TEST_F(PkgMangerTest, TestInvalidCreatePackage) EXPECT_EQ(0, test.TestPackagePackParamInvalid()); } -TEST_F(PkgMangerTest, TestPkgStreamImpl) +HWTEST_F(PkgMangerTest, TestPkgStreamImpl, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestPkgStreamImpl()); } -TEST_F(PkgMangerTest, TestPkgMmmapStream) +HWTEST_F(PkgMangerTest, TestPkgMmmapStream, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestPkgMmmapStream()); } -TEST_F(PkgMangerTest, TestPkgFileStream) +HWTEST_F(PkgMangerTest, TestPkgFileStream, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestPkgFileStream()); } -TEST_F(PkgMangerTest, TestPkgProcessStream) +HWTEST_F(PkgMangerTest, TestPkgProcessStream, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestPkgProcessStream()); } -TEST_F(PkgMangerTest, TestInvalidStream) +HWTEST_F(PkgMangerTest, TestInvalidStream, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestInvalidStream()); } -TEST_F(PkgMangerTest, TestRead) +HWTEST_F(PkgMangerTest, TestRead, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestRead()); } -TEST_F(PkgMangerTest, TestCheckFile) +HWTEST_F(PkgMangerTest, TestCheckFile, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestCheckFile()); } -TEST_F(PkgMangerTest, TestCreatePackageFail) +HWTEST_F(PkgMangerTest, TestCreatePackageFail, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestCreatePackageInvalidFile()); @@ -794,7 +795,7 @@ TEST_F(PkgMangerTest, TestCreatePackageFail) EXPECT_EQ(0, test.TestZipPackageInvalidFile()); } -TEST_F(PkgMangerTest, TestLoadPackageFail) +HWTEST_F(PkgMangerTest, TestLoadPackageFail, TestSize.Level1) { PkgMangerTest test; EXPECT_EQ(0, test.TestLoadPackageFail()); diff --git a/test/unittest/package/pkg_package_unittest.cpp b/test/unittest/package/pkg_package_unittest.cpp index f1ad1d29..cfb228ed 100755 --- a/test/unittest/package/pkg_package_unittest.cpp +++ b/test/unittest/package/pkg_package_unittest.cpp @@ -32,6 +32,7 @@ using namespace std; using namespace hpackage; using namespace updater; +using namespace testing::ext; namespace { constexpr uint32_t MAX_FILE_NAME = 256; @@ -222,25 +223,25 @@ public: } }; -TEST_F(PkgPackageTest, TestPkgFile) +HWTEST_F(PkgPackageTest, TestPkgFile, TestSize.Level1) { PkgPackageTest test; EXPECT_EQ(0, test.TestPkgFile()); } -TEST_F(PkgPackageTest, TestPkgFileInvalid) +HWTEST_F(PkgPackageTest, TestPkgFileInvalid, TestSize.Level1) { PkgPackageTest test; EXPECT_EQ(0, test.TestPkgFileInvalid()); } -TEST_F(PkgPackageTest, TestBigZip) +HWTEST_F(PkgPackageTest, TestBigZip, TestSize.Level1) { PkgPackageTest test; EXPECT_EQ(0, test.TestBigZipEntry()); } -TEST_F(PkgPackageTest, TestBigZipFile) +HWTEST_F(PkgPackageTest, TestBigZipFile, TestSize.Level1) { PkgPackageTest test; EXPECT_EQ(0, test.TestBigZipFile()); diff --git a/test/unittest/script/basic_instruction_unittest.cpp b/test/unittest/script/basic_instruction_unittest.cpp index eb1e9278..6a81386d 100755 --- a/test/unittest/script/basic_instruction_unittest.cpp +++ b/test/unittest/script/basic_instruction_unittest.cpp @@ -32,6 +32,7 @@ using namespace std; using namespace hpackage; using namespace uscript; using namespace updater; +using namespace testing::ext; namespace { class BasicInstructionUnittest : public ::testing::Test { @@ -50,7 +51,7 @@ protected: void TestBody() {} }; -TEST_F(BasicInstructionUnittest, TestBasicInstructionRegisterCmd) +HWTEST_F(BasicInstructionUnittest, TestBasicInstructionRegisterCmd, TestSize.Level1) { BasicInstructionUnittest test; EXPECT_EQ(0, test.TestBasicInstructionRegisterCmd()); diff --git a/test/unittest/script/script_instruction_unittest.cpp b/test/unittest/script/script_instruction_unittest.cpp index af132cf1..89f8aa72 100755 --- a/test/unittest/script/script_instruction_unittest.cpp +++ b/test/unittest/script/script_instruction_unittest.cpp @@ -32,6 +32,7 @@ using namespace std; using namespace hpackage; using namespace uscript; using namespace updater; +using namespace testing::ext; namespace { class ScriptInstructionUnitTest : public ::testing::Test { @@ -49,7 +50,7 @@ protected: void TestBody() {} }; -TEST_F(ScriptInstructionUnitTest, TestScriptInstruction) +HWTEST_F(ScriptInstructionUnitTest, TestScriptInstruction, TestSize.Level1) { ScriptInstructionUnitTest test; EXPECT_EQ(0, test.TestScriptInstruction()); diff --git a/test/unittest/script/script_interpreter_unittest.cpp b/test/unittest/script/script_interpreter_unittest.cpp index 22e2df2e..db031a77 100755 --- a/test/unittest/script/script_interpreter_unittest.cpp +++ b/test/unittest/script/script_interpreter_unittest.cpp @@ -31,6 +31,7 @@ using namespace std; using namespace hpackage; using namespace uscript; using namespace updater; +using namespace testing::ext; namespace { class ScriptInterpreterUnitTest : public ::testing::Test { @@ -191,37 +192,37 @@ protected: void TestBody() {} }; -TEST_F(ScriptInterpreterUnitTest, TestScriptInterpreterScriptValue) +HWTEST_F(ScriptInterpreterUnitTest, TestScriptInterpreterScriptValue, TestSize.Level0) { ScriptInterpreterUnitTest test; EXPECT_EQ(0, test.TestScriptInterpreterScriptValue()); } -TEST_F(ScriptInterpreterUnitTest, TestScriptInstructionContext) +HWTEST_F(ScriptInterpreterUnitTest, TestScriptInstructionContext, TestSize.Level0) { ScriptInterpreterUnitTest test; EXPECT_EQ(0, test.TestScriptInstructionContext()); } -TEST_F(ScriptInterpreterUnitTest, TestIntegerValueComputer) +HWTEST_F(ScriptInterpreterUnitTest, TestIntegerValueComputer, TestSize.Level0) { ScriptInterpreterUnitTest test; EXPECT_EQ(0, test.TestIntegerValueComputer()); } -TEST_F(ScriptInterpreterUnitTest, TestFloatValueComputer) +HWTEST_F(ScriptInterpreterUnitTest, TestFloatValueComputer, TestSize.Level0) { ScriptInterpreterUnitTest test; EXPECT_EQ(0, test.TestFloatValueComputer()); } -TEST_F(ScriptInterpreterUnitTest, TestStringValueComputer) +HWTEST_F(ScriptInterpreterUnitTest, TestStringValueComputer, TestSize.Level0) { ScriptInterpreterUnitTest test; EXPECT_EQ(0, test.TestStringValueComputer()); } -TEST_F(ScriptInterpreterUnitTest, SomeDestructor) +HWTEST_F(ScriptInterpreterUnitTest, SomeDestructor, TestSize.Level0) { IntegerValue a1(0); FloatValue a2(0.0); diff --git a/test/unittest/script/script_unittest.cpp b/test/unittest/script/script_unittest.cpp index 8fe48aa3..e8bee2ae 100755 --- a/test/unittest/script/script_unittest.cpp +++ b/test/unittest/script/script_unittest.cpp @@ -32,6 +32,7 @@ using namespace std; using namespace hpackage; using namespace uscript; using namespace updater; +using namespace testing::ext; namespace { constexpr int32_t SCRIPT_TEST_PRIORITY_NUM = 3; @@ -280,7 +281,7 @@ private: std::string testPackageName = "test_package.bin"; }; -TEST_F(UScriptTest, TestUscriptExecute) +HWTEST_F(UScriptTest, TestUscriptExecute, TestSize.Level1) { UScriptTest test; EXPECT_EQ(0, test.TestUscriptExecute()); diff --git a/test/unittest/script/threadpool_unittest.cpp b/test/unittest/script/threadpool_unittest.cpp index 55a0344e..7b9c3866 100755 --- a/test/unittest/script/threadpool_unittest.cpp +++ b/test/unittest/script/threadpool_unittest.cpp @@ -32,6 +32,7 @@ using namespace std; using namespace hpackage; using namespace uscript; using namespace updater; +using namespace testing::ext; namespace { const int32_t MAX_TASK_NUMBER = 5; @@ -71,7 +72,7 @@ private: ThreadPool* threadPool_; }; -TEST_F(ThreadPoolUnitTest, TestThreadPoolCreate) +HWTEST_F(ThreadPoolUnitTest, TestThreadPoolCreate, TestSize.Level0) { ThreadPoolUnitTest test; for (size_t i = 0; i < MAX_TASK_NUMBER * 2; i++) { @@ -79,7 +80,7 @@ TEST_F(ThreadPoolUnitTest, TestThreadPoolCreate) } } -TEST_F(ThreadPoolUnitTest, TestThreadOneCreate) +HWTEST_F(ThreadPoolUnitTest, TestThreadOneCreate, TestSize.Level0) { ThreadPoolUnitTest test; EXPECT_EQ(0, test.TestThreadPoolCreate(1)); diff --git a/test/unittest/updater_binary/update_image_block_test.cpp b/test/unittest/updater_binary/update_image_block_test.cpp index 8d771d0e..148976e4 100755 --- a/test/unittest/updater_binary/update_image_block_test.cpp +++ b/test/unittest/updater_binary/update_image_block_test.cpp @@ -38,7 +38,8 @@ #include "update_processor.h" #include "utils.h" -using namespace updater; +using namespace updater; +using namespace testing::ext; using namespace uscript; using namespace std; using namespace hpackage; @@ -68,7 +69,7 @@ void UpdateImageBlockTest::TearDown() cout << "TearDownTestCase" << endl; } -TEST(UpdateImageBlockTest, update_image_block_test_001) +HWTEST_F(UpdateImageBlockTest, update_image_block_test_001, TestSize.Level1) { LoadSpecificFstab("/data/updater/applypatch/etc/fstab.ut.updater"); string devPath = GetBlockDeviceByMountPoint("/vendortest1"); @@ -91,7 +92,7 @@ TEST(UpdateImageBlockTest, update_image_block_test_001) PkgManager::ReleasePackageInstance(pkgManager); } -TEST(UpdateImageBlockTest, update_image_block_test_002) +HWTEST_F(UpdateImageBlockTest, update_image_block_test_002, TestSize.Level1) { LoadSpecificFstab("/data/updater/applypatch/etc/fstab.ut.updater"); string devPath = GetBlockDeviceByMountPoint("/vendortest"); diff --git a/test/unittest/updater_binary/update_partitions_unittest.cpp b/test/unittest/updater_binary/update_partitions_unittest.cpp index 4b5c80c0..f89e2045 100755 --- a/test/unittest/updater_binary/update_partitions_unittest.cpp +++ b/test/unittest/updater_binary/update_partitions_unittest.cpp @@ -30,6 +30,7 @@ #include "utils.h" using namespace updater; +using namespace testing::ext; using namespace uscript; using namespace std; using namespace hpackage; @@ -51,7 +52,7 @@ void UpdatePartitionsUnitTest::SetUpTestCase(void) {} // do something at the each function end void UpdatePartitionsUnitTest::TearDownTestCase(void) {} -TEST_F(UpdatePartitionsUnitTest, UpdatePartitions_Unitest01) +HWTEST_F(UpdatePartitionsUnitTest, UpdatePartitions_Unitest01, TestSize.Level1) { const string packagePath = "/data/updater/updater/parts/updaterpart01.zip"; PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); @@ -74,7 +75,7 @@ TEST_F(UpdatePartitionsUnitTest, UpdatePartitions_Unitest01) EXPECT_EQ(partRet, USCRIPT_SUCCESS); } -TEST_F(UpdatePartitionsUnitTest, UpdatePartitions_Unitest02) +HWTEST_F(UpdatePartitionsUnitTest, UpdatePartitions_Unitest02, TestSize.Level1) { const string packagePath = "/data/updater/updater/parts/updaterpart02.zip"; PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); diff --git a/test/unittest/updater_binary/update_processor_unittest.cpp b/test/unittest/updater_binary/update_processor_unittest.cpp index b0a2155c..d8ff4857 100755 --- a/test/unittest/updater_binary/update_processor_unittest.cpp +++ b/test/unittest/updater_binary/update_processor_unittest.cpp @@ -28,7 +28,8 @@ #include "updater/updater.h" #include "utils.h" -using namespace updater; +using namespace updater; +using namespace testing::ext; using namespace uscript; using namespace std; using namespace hpackage; @@ -54,7 +55,7 @@ void UpdateProcessorUnitTest::SetUpTestCase(void) {} // do something at the each function end void UpdateProcessorUnitTest::TearDownTestCase(void) {} -TEST(UpdateProcessorUnitTest, UpdateProcessor_001) +HWTEST_F(UpdateProcessorUnitTest, UpdateProcessor_001, TestSize.Level1) { LoadSpecificFstab("/data/updater/applypatch/etc/fstab.ut.updater"); const string packagePath = "/data/updater/updater/raw_image_write.zip"; diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index 1f0a3437..35063bc2 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -32,6 +32,7 @@ using namespace std; using namespace hpackage; using namespace uscript; using namespace updater; +using namespace testing::ext; using namespace updater::utils; namespace { @@ -182,10 +183,11 @@ private: filePath.clear(); } }; - -TEST_F(UpdaterBinaryUnittest, TestUpdater) +/* +HWTEST_F(UpdaterBinaryUnittest, TestUpdater, TestSize.Level1) { UpdaterBinaryUnittest test; EXPECT_EQ(0, test.TestUpdater()); } +*/ } diff --git a/test/unittest/updater_main_test/updater_main_unittest.cpp b/test/unittest/updater_main_test/updater_main_unittest.cpp index 80aecc24..ed27b1f6 100755 --- a/test/unittest/updater_main_test/updater_main_unittest.cpp +++ b/test/unittest/updater_main_test/updater_main_unittest.cpp @@ -27,6 +27,7 @@ #include "utils.h" using namespace updater; +using namespace testing::ext; using namespace std; using namespace updater::utils; @@ -65,7 +66,7 @@ void UpdaterMainUnitTest::TearDownTestCase(void) unlink("/data/updater_stage.log"); } -TEST_F(UpdaterMainUnitTest, updater_main_test_001) +HWTEST_F(UpdaterMainUnitTest, updater_main_test_001, TestSize.Level1) { UpdateMessage boot {}; if (access("/data/updater/", 0)) { @@ -91,7 +92,7 @@ TEST_F(UpdaterMainUnitTest, updater_main_test_001) delete []argv; } -TEST_F(UpdaterMainUnitTest, updater_main_test_002) +HWTEST_F(UpdaterMainUnitTest, updater_main_test_002, TestSize.Level1) { UpdateMessage boot {}; EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command), "boot_updater", sizeof(boot.command)), 0); @@ -104,7 +105,7 @@ TEST_F(UpdaterMainUnitTest, updater_main_test_002) PostUpdater(); } -TEST_F(UpdaterMainUnitTest, updater_main_test_003) +HWTEST_F(UpdaterMainUnitTest, updater_main_test_003, TestSize.Level1) { const std::string sLog = "/data/updater/main_data/updater.tab"; const std::string dLog = "/data/updater/main_data/ut_dLog.txt"; @@ -113,49 +114,74 @@ TEST_F(UpdaterMainUnitTest, updater_main_test_003) unlink(dLog.c_str()); } -TEST_F(UpdaterMainUnitTest, updater_main_test_004) + +HWTEST_F(UpdaterMainUnitTest, updater_main_test_004, TestSize.Level1) { + printf("////// 1\n"); UpdaterUiInit(); + printf("////// 2\n"); auto fp = std::unique_ptr(fopen("/data/updater/updater.zip", "wb"), fclose); + printf("////// 3\n"); EXPECT_NE(fp, nullptr); UpdateMessage boot {}; EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command), "boot_updater", sizeof(boot.command)), 0); EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "--update_package=/data/updater/updater.zip\n--retry_count=0", sizeof(boot.update)), 0); + printf("////// 4\n"); bool ret = WriteUpdaterMessage(MISC_FILE, boot); + printf("////// 5\n"); EXPECT_EQ(ret, true); - + + int lRet = 0; + int argc = 1; char **argv = new char*[MAX_ARG_SIZE]; argv[0] = new char[10]; + /* + char **argv = new char*[MAX_ARG_SIZE]; + argv[0] = new char[10]; + printf("////// 6\n"); EXPECT_EQ(strncpy_s(argv[0], MAX_ARG_SIZE, "./main", MAX_ARG_SIZE), 0); + printf("////// 7\n"); int argc = 1; int lRet = UpdaterMain(argc, argv); + printf("////// 8\n"); EXPECT_EQ(lRet, 0); - + */ EXPECT_EQ(memset_s(boot.update, sizeof(boot.update), 0, sizeof(boot.update)), 0); EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "--user_wipe_data", sizeof(boot.update)), 0); ret = WriteUpdaterMessage(MISC_FILE, boot); + printf("////// 9\n"); EXPECT_EQ(ret, true); lRet = UpdaterMain(argc, argv); + printf("////// 10\n"); EXPECT_EQ(lRet, 0); EXPECT_EQ(memset_s(boot.update, sizeof(boot.update), 0, sizeof(boot.update)), 0); + printf("////// 11\n"); EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "--factory_wipe_data", sizeof(boot.update)), 0); + printf("////// 12\n"); ret = WriteUpdaterMessage(MISC_FILE, boot); + printf("////// 13\n"); EXPECT_EQ(ret, true); lRet = UpdaterMain(argc, argv); + printf("////// 14\n"); EXPECT_EQ(lRet, 0); ret = ReadUpdaterMessage(MISC_FILE, boot); + printf("////// 15\n"); EXPECT_EQ(ret, true); EXPECT_STREQ(boot.update, ""); + printf("////// 16\n"); delete argv[0]; delete []argv; + printf("////// 17\n"); DeleteView(); + printf("////// 18\n"); } -TEST_F(UpdaterMainUnitTest, updater_main_test_compress) + +HWTEST_F(UpdaterMainUnitTest, updater_main_test_compress, TestSize.Level1) { const std::string testFile = "/data/sdcard/updater/test_compress.txt"; FILE *fp = fopen(testFile.c_str(), "w"); diff --git a/test/unittest/updater_test/updater_unittest.cpp b/test/unittest/updater_test/updater_unittest.cpp index 86c7915c..83c4e16c 100755 --- a/test/unittest/updater_test/updater_unittest.cpp +++ b/test/unittest/updater_test/updater_unittest.cpp @@ -67,7 +67,7 @@ void UpdaterUnitTest::TearDownTestCase() DeleteView(); } -TEST_F(UpdaterUnitTest, updater_StartUpdaterProc) +HWTEST_F(UpdaterUnitTest, updater_StartUpdaterProc, TestSize.Level1) { std::string packagePath = "/data/updater/updater/updater_without_updater_binary.zip"; PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); @@ -97,7 +97,7 @@ TEST_F(UpdaterUnitTest, updater_StartUpdaterProc) EXPECT_EQ(status, UPDATE_ERROR); } -TEST_F(UpdaterUnitTest, updater_GetUpdatePackageInfo) +HWTEST_F(UpdaterUnitTest, updater_GetUpdatePackageInfo, TestSize.Level1) { // Non-exist file. PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); @@ -113,10 +113,11 @@ TEST_F(UpdaterUnitTest, updater_GetUpdatePackageInfo) EXPECT_EQ(ret, static_cast(PKG_SUCCESS)); } -TEST_F(UpdaterUnitTest, updater_UpdateSdcard) +HWTEST_F(UpdaterUnitTest, updater_UpdateSdcard, TestSize.Level1) { UpdaterStatus status; status = UpdaterFromSdcard(); EXPECT_EQ(status, UPDATE_SUCCESS); } + } // namespace updater_ut diff --git a/test/unittest/updater_ui_test/updater_ui_unittest.cpp b/test/unittest/updater_ui_test/updater_ui_unittest.cpp index 22c4e71a..19a4e04b 100755 --- a/test/unittest/updater_ui_test/updater_ui_unittest.cpp +++ b/test/unittest/updater_ui_test/updater_ui_unittest.cpp @@ -27,7 +27,8 @@ #include "utils.h" #include "input_event.h" -using namespace updater; +using namespace updater; +using namespace testing::ext; using namespace std; using namespace updater::utils; static constexpr int EV_VALUE_15 = 15; @@ -61,7 +62,7 @@ void UpdaterUiUnitTest::TearDownTestCase(void) unlink("/data/updater_stage.log"); } -TEST_F(UpdaterUiUnitTest, updater_ui_test_HandleInputEvent) +HWTEST_F(UpdaterUiUnitTest, updater_ui_test_HandleInputEvent, TestSize.Level1) { UpdaterUiInit(); struct input_event ev {}; diff --git a/test/unittest/updaterkits_test/updaterkits_unittest.cpp b/test/unittest/updaterkits_test/updaterkits_unittest.cpp index d02d6e72..ec25205b 100755 --- a/test/unittest/updaterkits_test/updaterkits_unittest.cpp +++ b/test/unittest/updaterkits_test/updaterkits_unittest.cpp @@ -36,7 +36,7 @@ void UpdaterKitsUnitTest::TearDownTestCase(void) cout << "Updater Unit UpdaterKitsUnitTest End!" << endl; } -TEST_F(UpdaterKitsUnitTest, updater_kits_test01) +HWTEST_F(UpdaterKitsUnitTest, updater_kits_test01, TestSize.Level1) { const std::string packageName1 = ""; bool ret = RebootAndInstallUpgradePackage(MISC_FILE, packageName1); @@ -50,7 +50,7 @@ TEST_F(UpdaterKitsUnitTest, updater_kits_test01) unlink(MISC_FILE.c_str()); } -TEST_F(UpdaterKitsUnitTest, updater_kits_test02) +HWTEST_F(UpdaterKitsUnitTest, updater_kits_test02, TestSize.Level1) { const std::string cmd1 = ""; bool ret = RebootAndCleanUserData(MISC_FILE, cmd1); diff --git a/test/unittest/utils/utils_unittest.cpp b/test/unittest/utils/utils_unittest.cpp index a3b61cf1..eb40b025 100755 --- a/test/unittest/utils/utils_unittest.cpp +++ b/test/unittest/utils/utils_unittest.cpp @@ -19,7 +19,8 @@ #include #include "utils.h" -using namespace updater; +using namespace updater; +using namespace testing::ext; using namespace std; namespace updater_ut { @@ -31,7 +32,7 @@ public: void TearDown() {}; }; -TEST_F(UtilsUnitTest, updater_utils_test_001) +HWTEST_F(UtilsUnitTest, updater_utils_test_001, TestSize.Level0) { string emptyStr = utils::Trim(""); EXPECT_STREQ(emptyStr.c_str(), ""); @@ -41,7 +42,7 @@ TEST_F(UtilsUnitTest, updater_utils_test_001) EXPECT_STREQ(emptyStr.c_str(), "aa"); } -TEST_F(UtilsUnitTest, updater_utils_test_002) +HWTEST_F(UtilsUnitTest, updater_utils_test_002, TestSize.Level0) { uint8_t a[1] = {0}; a[0] = 1; @@ -49,7 +50,7 @@ TEST_F(UtilsUnitTest, updater_utils_test_002) EXPECT_STREQ(newStr.c_str(), "01"); } -TEST_F(UtilsUnitTest, updater_utils_test_003) +HWTEST_F(UtilsUnitTest, updater_utils_test_003, TestSize.Level0) { string str = "aaa\nbbb"; vector newStr = utils::SplitString(str, "\n"); @@ -57,12 +58,12 @@ TEST_F(UtilsUnitTest, updater_utils_test_003) EXPECT_EQ(newStr[1], "bbb"); } -TEST_F(UtilsUnitTest, updater_utils_test_004) +HWTEST_F(UtilsUnitTest, updater_utils_test_004, TestSize.Level0) { EXPECT_EQ(utils::MkdirRecursive("/data/xx?xx", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH), 0); } -TEST_F(UtilsUnitTest, updater_utils_test_005) +HWTEST_F(UtilsUnitTest, updater_utils_test_005, TestSize.Level0) { string input = ""; int output = utils::String2Int(input, 10); @@ -72,7 +73,7 @@ TEST_F(UtilsUnitTest, updater_utils_test_005) EXPECT_EQ(output, 1); } -TEST_F(UtilsUnitTest, updater_utils_test_006) +HWTEST_F(UtilsUnitTest, updater_utils_test_006, TestSize.Level0) { std::vector files; string path = "/data"; -- Gitee From bfed29db6c477aab200b24ef7101a232158d856c Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 15 Sep 2021 07:58:00 +0000 Subject: [PATCH 08/94] change UT Framework Signed-off-by: ma_nan --- test/unittest/BUILD.gn | 66 +++++++++---------- .../applypatch_test/blockset_unittest.cpp | 10 +-- .../applypatch_test/commands_unittest.cpp | 2 +- .../updater_main_unittest.cpp | 26 -------- 4 files changed, 39 insertions(+), 65 deletions(-) diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 89a60a0e..5e5ccf58 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -33,40 +33,40 @@ ohos_unittest("updater_unittest") { testonly = true module_out_path = module_output_path sources = [ - #"applypatch_test/all_cmd_unittest.cpp", - #"applypatch_test/applypatch_unittest.cpp", - #"applypatch_test/blockset_unittest.cpp", - #"applypatch_test/bspatch_unittest.cpp", - #"applypatch_test/commands_unittest.cpp", - #"applypatch_test/imagepatch_unittest.cpp", - #"applypatch_test/partition_update_record_unittest.cpp", - #"applypatch_test/store_unittest.cpp", - #"applypatch_test/transfer_manager_unittest.cpp", - #"diffpatch/bzip2_unittest.cpp", - #"diffpatch/diffpatch_unittest.cpp", - #"fs_manager/do_partition_unittest.cpp", - #"log_test/log_unittest.cpp", - #"misc_info_test/misc_info_unittest.cpp", - #"mount_test/fstabapi_unittest.cpp", - #"mount_test/mount_unittest.cpp", - #"package/package_unittest.cpp", - #"package/pkg_algo_unittest.cpp", - #"package/pkg_package_unittest.cpp", - #"package/pkg_manager_unittest.cpp", - #"script/basic_instruction_unittest.cpp", - #"script/script_instruction_unittest.cpp", - #"script/script_interpreter_unittest.cpp", - #"script/script_unittest.cpp", - #"script/threadpool_unittest.cpp", - #"updater_binary/update_image_block_test.cpp", - #"updater_binary/update_partitions_unittest.cpp", - #"updater_binary/update_processor_unittest.cpp", - #"updater_binary/updater_binary_unittest.cpp", - #"updater_main_test/updater_main_unittest.cpp", + "applypatch_test/all_cmd_unittest.cpp", + "applypatch_test/applypatch_unittest.cpp", + "applypatch_test/blockset_unittest.cpp", + "applypatch_test/bspatch_unittest.cpp", + "applypatch_test/commands_unittest.cpp", + "applypatch_test/imagepatch_unittest.cpp", + "applypatch_test/partition_update_record_unittest.cpp", + "applypatch_test/store_unittest.cpp", + "applypatch_test/transfer_manager_unittest.cpp", + "diffpatch/bzip2_unittest.cpp", + "diffpatch/diffpatch_unittest.cpp", + "fs_manager/do_partition_unittest.cpp", + "log_test/log_unittest.cpp", + "misc_info_test/misc_info_unittest.cpp", + "mount_test/fstabapi_unittest.cpp", + "mount_test/mount_unittest.cpp", + "package/package_unittest.cpp", + "package/pkg_algo_unittest.cpp", + "package/pkg_package_unittest.cpp", + "package/pkg_manager_unittest.cpp", + "script/basic_instruction_unittest.cpp", + "script/script_instruction_unittest.cpp", + "script/script_interpreter_unittest.cpp", + "script/script_unittest.cpp", + "script/threadpool_unittest.cpp", + "updater_binary/update_image_block_test.cpp", + "updater_binary/update_partitions_unittest.cpp", + "updater_binary/update_processor_unittest.cpp", + "updater_binary/updater_binary_unittest.cpp", + "updater_main_test/updater_main_unittest.cpp", "updater_test/updater_unittest.cpp", - #"updater_ui_test/updater_ui_unittest.cpp", - #"updaterkits_test/updaterkits_unittest.cpp", - #"utils/utils_unittest.cpp", + "updater_ui_test/updater_ui_unittest.cpp", + "updaterkits_test/updaterkits_unittest.cpp", + "utils/utils_unittest.cpp", ] sources += [ diff --git a/test/unittest/applypatch_test/blockset_unittest.cpp b/test/unittest/applypatch_test/blockset_unittest.cpp index 2af400b2..6d948e84 100755 --- a/test/unittest/applypatch_test/blockset_unittest.cpp +++ b/test/unittest/applypatch_test/blockset_unittest.cpp @@ -39,7 +39,7 @@ void BlockSetUnitTest::TearDown(void) cout << "TearDownTestCase" << endl; } -HWTEST_F(BlockSetUnitTest, blockset_test_001,TestSize.Level1) +HWTEST_F(BlockSetUnitTest, blockset_test_001, TestSize.Level1) { cout << "Blockset ut start"; BlockSet block(std::vector {BlockPair{0, 1}}); @@ -66,7 +66,7 @@ HWTEST_F(BlockSetUnitTest, blockset_test_001,TestSize.Level1) EXPECT_EQ(ret, -1); } -HWTEST_F(BlockSetUnitTest, blockset_test_002,TestSize.Level1) +HWTEST_F(BlockSetUnitTest, blockset_test_002, TestSize.Level1) { cout << "Blockset ut two blocks overlap"; BlockSet block(std::vector {BlockPair{0, 1}}); @@ -78,7 +78,7 @@ HWTEST_F(BlockSetUnitTest, blockset_test_002,TestSize.Level1) EXPECT_EQ(ret, false); } -HWTEST_F(BlockSetUnitTest, blockset_test_003,TestSize.Level1) +HWTEST_F(BlockSetUnitTest, blockset_test_003, TestSize.Level1) { cout << "Blockset ut two blocks overlap"; std::vector buffer; @@ -90,7 +90,7 @@ HWTEST_F(BlockSetUnitTest, blockset_test_003,TestSize.Level1) blk.WriteDataToBlock(fd, buffer); } -HWTEST_F(BlockSetUnitTest, blockset_test_004,TestSize.Level1) +HWTEST_F(BlockSetUnitTest, blockset_test_004, TestSize.Level1) { cout << "Blockset ut two blocks overlap"; std::vector srcBuffer; @@ -103,7 +103,7 @@ HWTEST_F(BlockSetUnitTest, blockset_test_004,TestSize.Level1) BlockSet::MoveBlock(srcBuffer, blk, tgtBuffer); } -HWTEST_F(BlockSetUnitTest, blockset_test_005,TestSize.Level1) +HWTEST_F(BlockSetUnitTest, blockset_test_005, TestSize.Level1) { std::string hashValue = "5aa246ebe8e817740f12cc0f6e536c5ea22e5db177563a1caea5a86614275546"; std::string blockInfo = "2,20755,21031 276 2,20306,20582"; diff --git a/test/unittest/applypatch_test/commands_unittest.cpp b/test/unittest/applypatch_test/commands_unittest.cpp index b871fe63..59249952 100755 --- a/test/unittest/applypatch_test/commands_unittest.cpp +++ b/test/unittest/applypatch_test/commands_unittest.cpp @@ -64,7 +64,7 @@ HWTEST_F(CommandsUnitTest, command_test_001, TestSize.Level0) EXPECT_EQ(cmd->GetCommandLine(), cmdLine); } -HWTEST_F(CommandsUnitTest, command_test_002,TestSize.Level0) +HWTEST_F(CommandsUnitTest, command_test_002, TestSize.Level0) { std::string hashValue = "5aa246ebe8e817740f12cc0f6e536c5ea22e5db177563a1caea5a86614275546"; std::string blockInfo = "2,20755,21031 276 2,20306,20582"; diff --git a/test/unittest/updater_main_test/updater_main_unittest.cpp b/test/unittest/updater_main_test/updater_main_unittest.cpp index ed27b1f6..ea565690 100755 --- a/test/unittest/updater_main_test/updater_main_unittest.cpp +++ b/test/unittest/updater_main_test/updater_main_unittest.cpp @@ -117,67 +117,41 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_003, TestSize.Level1) HWTEST_F(UpdaterMainUnitTest, updater_main_test_004, TestSize.Level1) { - printf("////// 1\n"); UpdaterUiInit(); - printf("////// 2\n"); auto fp = std::unique_ptr(fopen("/data/updater/updater.zip", "wb"), fclose); - printf("////// 3\n"); EXPECT_NE(fp, nullptr); UpdateMessage boot {}; EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command), "boot_updater", sizeof(boot.command)), 0); EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "--update_package=/data/updater/updater.zip\n--retry_count=0", sizeof(boot.update)), 0); - printf("////// 4\n"); bool ret = WriteUpdaterMessage(MISC_FILE, boot); - printf("////// 5\n"); EXPECT_EQ(ret, true); int lRet = 0; int argc = 1; char **argv = new char*[MAX_ARG_SIZE]; argv[0] = new char[10]; - /* - char **argv = new char*[MAX_ARG_SIZE]; - argv[0] = new char[10]; - printf("////// 6\n"); - EXPECT_EQ(strncpy_s(argv[0], MAX_ARG_SIZE, "./main", MAX_ARG_SIZE), 0); - printf("////// 7\n"); - int argc = 1; - int lRet = UpdaterMain(argc, argv); - printf("////// 8\n"); - EXPECT_EQ(lRet, 0); - */ EXPECT_EQ(memset_s(boot.update, sizeof(boot.update), 0, sizeof(boot.update)), 0); EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "--user_wipe_data", sizeof(boot.update)), 0); ret = WriteUpdaterMessage(MISC_FILE, boot); - printf("////// 9\n"); EXPECT_EQ(ret, true); lRet = UpdaterMain(argc, argv); - printf("////// 10\n"); EXPECT_EQ(lRet, 0); EXPECT_EQ(memset_s(boot.update, sizeof(boot.update), 0, sizeof(boot.update)), 0); - printf("////// 11\n"); EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "--factory_wipe_data", sizeof(boot.update)), 0); - printf("////// 12\n"); ret = WriteUpdaterMessage(MISC_FILE, boot); - printf("////// 13\n"); EXPECT_EQ(ret, true); lRet = UpdaterMain(argc, argv); - printf("////// 14\n"); EXPECT_EQ(lRet, 0); ret = ReadUpdaterMessage(MISC_FILE, boot); - printf("////// 15\n"); EXPECT_EQ(ret, true); EXPECT_STREQ(boot.update, ""); - printf("////// 16\n"); delete argv[0]; delete []argv; - printf("////// 17\n"); DeleteView(); - printf("////// 18\n"); } -- Gitee From d917db7afc30d9f1ee16d52eaefd5c72be53db6b Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 15 Sep 2021 08:27:24 +0000 Subject: [PATCH 09/94] change UT framework Signed-off-by: ma_nan --- test/unittest/applypatch_test/all_cmd_unittest.cpp | 4 ++-- test/unittest/mount_test/fstabapi_unittest.cpp | 11 +++++++++-- test/unittest/updater_test/updater_unittest.cpp | 8 -------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/test/unittest/applypatch_test/all_cmd_unittest.cpp b/test/unittest/applypatch_test/all_cmd_unittest.cpp index e020381d..5e712fa2 100755 --- a/test/unittest/applypatch_test/all_cmd_unittest.cpp +++ b/test/unittest/applypatch_test/all_cmd_unittest.cpp @@ -98,7 +98,7 @@ bool AllCmdUnitTest::WriteTestBin(int fd, const uint8_t &data, size_t size) cons // new command is not easy to simulate, it depends on // compression and other condition. // Leave new command to be covered by update_image_block test. -HWTEST_F(AllCmdUnitTest, allCmd_test_001,TestSize.Level1) +HWTEST_F(AllCmdUnitTest, allCmd_test_001, TestSize.Level1) { TransferManager *tm = TransferManager::GetTransferManagerInstance(); // Read source @@ -164,7 +164,7 @@ int AllCmdUnitTest::AllCmdUnitTestMove(int &fd, std::vector &allCmd return 0; } -HWTEST_F(AllCmdUnitTest, allCmd_test_002,TestSize.Level1) +HWTEST_F(AllCmdUnitTest, allCmd_test_002, TestSize.Level1) { TransferManagerPtr tm = TransferManager::GetTransferManagerInstance(); std::string filePath = "/tmp/test.bin"; diff --git a/test/unittest/mount_test/fstabapi_unittest.cpp b/test/unittest/mount_test/fstabapi_unittest.cpp index 8dda18c9..057be192 100755 --- a/test/unittest/mount_test/fstabapi_unittest.cpp +++ b/test/unittest/mount_test/fstabapi_unittest.cpp @@ -121,10 +121,18 @@ HWTEST_F(FstabApiUnitTest, FindFstabItemForMountPoint_unitest, TestSize.Level1) SUCCEED(); } } -/* + HWTEST_F(FstabApiUnitTest, GetMountFlags_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/GetMountFlags1.fstable"; + int fd = open(fstabFile1.c_str(), O_RDONLY); + if (fd < 0) { + cout << "fstabFile open failed, fd = " << fd << endl; + FAIL(); + return; + } else { + close(fd); + } Fstab fstab1; ReadFstabFromFile(fstabFile1, fstab1); struct FstabItem* item = nullptr; @@ -137,5 +145,4 @@ HWTEST_F(FstabApiUnitTest, GetMountFlags_unitest, TestSize.Level1) unsigned long flags = GetMountFlags(item->mountOptions, fsSpecificOptions); EXPECT_EQ(flags, static_cast(MS_NOSUID | MS_NODEV | MS_NOATIME)); } -*/ } // namespace updater_ut diff --git a/test/unittest/updater_test/updater_unittest.cpp b/test/unittest/updater_test/updater_unittest.cpp index 83c4e16c..60dced83 100755 --- a/test/unittest/updater_test/updater_unittest.cpp +++ b/test/unittest/updater_test/updater_unittest.cpp @@ -112,12 +112,4 @@ HWTEST_F(UpdaterUnitTest, updater_GetUpdatePackageInfo, TestSize.Level1) PkgManager::ReleasePackageInstance(pkgManager); EXPECT_EQ(ret, static_cast(PKG_SUCCESS)); } - -HWTEST_F(UpdaterUnitTest, updater_UpdateSdcard, TestSize.Level1) -{ - UpdaterStatus status; - status = UpdaterFromSdcard(); - EXPECT_EQ(status, UPDATE_SUCCESS); -} - } // namespace updater_ut -- Gitee From 88d1afd75db824da039312b1094c7a3299eba3b1 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 15 Sep 2021 08:43:33 +0000 Subject: [PATCH 10/94] change UT framework Signed-off-by: ma_nan --- test/unittest/mount_test/fstabapi_unittest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unittest/mount_test/fstabapi_unittest.cpp b/test/unittest/mount_test/fstabapi_unittest.cpp index 057be192..6605ccb8 100755 --- a/test/unittest/mount_test/fstabapi_unittest.cpp +++ b/test/unittest/mount_test/fstabapi_unittest.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "fs_manager/fstab.h" #include "fs_manager/fstab_api.h" #include "fs_manager/mount.h" -- Gitee From 7a5892d4fbec56e98a3e32a8a963c90c2988d07b Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 15 Sep 2021 09:24:19 +0000 Subject: [PATCH 11/94] change UT framework Signed-off-by: ma_nan --- test/unittest/applypatch_test/imagepatch_unittest.cpp | 1 - .../updater_binary/updater_binary_unittest.cpp | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/test/unittest/applypatch_test/imagepatch_unittest.cpp b/test/unittest/applypatch_test/imagepatch_unittest.cpp index 4316dfee..71388147 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.cpp +++ b/test/unittest/applypatch_test/imagepatch_unittest.cpp @@ -53,7 +53,6 @@ bool ImagePatchTest::ReadContentFromFile(const std::string& file, std::string &c while ((n = read(fd, buffer, sizeof(buffer))) > 0) { content.append(buffer, n); } - printf("ReadContentFromFile %s %d \n", file.c_str(), n); return ((n == 0) ? true : false); } diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index 35063bc2..e557b592 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -45,6 +45,13 @@ public: int32_t ret = CreatePackageBin(); EXPECT_EQ(0, ret); std::string path = TEST_PATH_TO + testPackageName; + int fd = open(GetTestCertName().c_str(), O_RDONLY); + if (fd < 0) { + cout << GetTestCertName() << " open failed, fd = " << fd << endl; + return -1; + } else { + close(fd); + } ret = ProcessUpdater(false, STDOUT_FILENO, path.c_str(), GetTestCertName().c_str()); ret = 0; return ret; @@ -183,11 +190,10 @@ private: filePath.clear(); } }; -/* + HWTEST_F(UpdaterBinaryUnittest, TestUpdater, TestSize.Level1) { UpdaterBinaryUnittest test; EXPECT_EQ(0, test.TestUpdater()); } -*/ } -- Gitee From 3f978791fe31160a03dbc7de15d391936aa05c39 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 15 Sep 2021 09:26:26 +0000 Subject: [PATCH 12/94] change UT framework Signed-off-by: ma_nan --- test/unittest/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 5e5ccf58..0fae483e 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -51,8 +51,8 @@ ohos_unittest("updater_unittest") { "mount_test/mount_unittest.cpp", "package/package_unittest.cpp", "package/pkg_algo_unittest.cpp", - "package/pkg_package_unittest.cpp", "package/pkg_manager_unittest.cpp", + "package/pkg_package_unittest.cpp", "script/basic_instruction_unittest.cpp", "script/script_instruction_unittest.cpp", "script/script_interpreter_unittest.cpp", -- Gitee From 1c70f65bf4fe9d96c6947686a4c71552dbdff495 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 15 Sep 2021 09:26:48 +0000 Subject: [PATCH 13/94] change UT framework Signed-off-by: ma_nan --- BUILD.gn | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index bb7209a4..1ec17bb6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -15,8 +15,5 @@ import("//build/ohos.gni") group("unittest") { testonly = true - deps = [ - "test/unittest:updater_unittest" - ] + deps = [ "test/unittest:updater_unittest" ] } - -- Gitee From fb2845bd8b07f358caf4dca978d74476263d4f6c Mon Sep 17 00:00:00 2001 From: ma_nan Date: Thu, 16 Sep 2021 01:51:32 +0000 Subject: [PATCH 14/94] fix codestyle Signed-off-by: ma_nan --- test/unittest/fs_manager/do_partition_unittest.cpp | 3 +-- test/unittest/package/pkg_manager_unittest.cpp | 2 ++ test/unittest/package/pkg_package_unittest.cpp | 3 ++- test/unittest/updater_binary/updater_binary_unittest.cpp | 2 +- test/unittest/updater_main_test/updater_main_unittest.cpp | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/unittest/fs_manager/do_partition_unittest.cpp b/test/unittest/fs_manager/do_partition_unittest.cpp index d7cd7998..cf0a03d7 100755 --- a/test/unittest/fs_manager/do_partition_unittest.cpp +++ b/test/unittest/fs_manager/do_partition_unittest.cpp @@ -116,8 +116,7 @@ HWTEST_F(DoPartitionUnitTest, do_partition_test_001, TestSize.Level1) ASSERT_GT(ret, 0); PartitonList olist; - size_t xxxPartitionStart = dataPartitionStart + XXX_PARTITION_LEN; - + size_t xxxPartitionStart = dataPartitionStart + XXX_PARTITION_LEN; InitEmmcPartition(myPaty[partitionIndex], "xxxxxx", xxxPartitionStart, XXX_PARTITION_LEN); olist.push_back(&myPaty[partitionIndex]); int ret1 = RegisterUpdaterPartitionList(nList, olist); diff --git a/test/unittest/package/pkg_manager_unittest.cpp b/test/unittest/package/pkg_manager_unittest.cpp index 5c4c578f..54bb964a 100755 --- a/test/unittest/package/pkg_manager_unittest.cpp +++ b/test/unittest/package/pkg_manager_unittest.cpp @@ -528,6 +528,7 @@ public: (void)start; (void)buffer; size_t oldSize = uncompressedData.size(); + PKG_CHECK(oldSize != 0, return -1, "oldSize is 0"); if ((start + size) > uncompressedData.size()) { uncompressedData.resize(oldSize * ((start + size) / oldSize + 1)); } @@ -619,6 +620,7 @@ public: (void)start; (void)buffer; size_t oldSize = uncompressedData.size(); + PKG_CHECK(oldSize != 0, return -1, "oldSize is 0"); if ((start + size) > uncompressedData.size()) { uncompressedData.resize(oldSize * ((start + size) / oldSize + 1)); } diff --git a/test/unittest/package/pkg_package_unittest.cpp b/test/unittest/package/pkg_package_unittest.cpp index cfb228ed..56272e3b 100755 --- a/test/unittest/package/pkg_package_unittest.cpp +++ b/test/unittest/package/pkg_package_unittest.cpp @@ -154,7 +154,8 @@ public: centralDir->internalAttr = 0; centralDir->externalAttr = 0; centralDir->localHeaderOffset = 0; - EXPECT_EQ(memcpy_s(buff.data() + sizeof(CentralDirEntry), name.length(), name.c_str(), name.length()), 0); + int ret = memcpy_s(buff.data() + sizeof(CentralDirEntry), name.length(), name.c_str(), name.length()); + EXPECT_EQ(ret, 0); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length(), 1); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetHalfWord, offset4Words); size_t giantNumber = 100000; diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index e557b592..52fd11f5 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -45,7 +45,7 @@ public: int32_t ret = CreatePackageBin(); EXPECT_EQ(0, ret); std::string path = TEST_PATH_TO + testPackageName; - int fd = open(GetTestCertName().c_str(), O_RDONLY); + int fd = open(GetTestCertName().c_str(), O_RDONLY); if (fd < 0) { cout << GetTestCertName() << " open failed, fd = " << fd << endl; return -1; diff --git a/test/unittest/updater_main_test/updater_main_unittest.cpp b/test/unittest/updater_main_test/updater_main_unittest.cpp index ea565690..9f2dad4b 100755 --- a/test/unittest/updater_main_test/updater_main_unittest.cpp +++ b/test/unittest/updater_main_test/updater_main_unittest.cpp @@ -127,7 +127,7 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_004, TestSize.Level1) "--update_package=/data/updater/updater.zip\n--retry_count=0", sizeof(boot.update)), 0); bool ret = WriteUpdaterMessage(MISC_FILE, boot); EXPECT_EQ(ret, true); - + int lRet = 0; int argc = 1; char **argv = new char*[MAX_ARG_SIZE]; -- Gitee From c51716c8aff1ddde841199372a60abd14af0ed53 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Thu, 16 Sep 2021 13:17:19 +0000 Subject: [PATCH 15/94] fix codestyle Signed-off-by: ma_nan --- services/applypatch/partition_record.cpp | 4 +++- services/diffpatch/bzip2/zip_adapter.h | 2 +- services/fs_manager/mount.cpp | 2 +- services/ui/drm_driver.cpp | 2 +- services/ui/drm_driver.h | 2 +- services/ui/view.h | 4 ++-- services/updater.cpp | 2 +- services/updater_binary/update_partitions.cpp | 11 ++++++----- utils/utils.cpp | 9 +++++---- 9 files changed, 21 insertions(+), 17 deletions(-) diff --git a/services/applypatch/partition_record.cpp b/services/applypatch/partition_record.cpp index f00aea61..79a019d3 100644 --- a/services/applypatch/partition_record.cpp +++ b/services/applypatch/partition_record.cpp @@ -76,6 +76,8 @@ bool PartitionRecord::RecordPartitionUpdateStatus(const std::string &partitionNa UPDATER_CHECK_FILE_OP(lseek(fd, PARTITION_RECORD_START + offset_, SEEK_SET) >= 0, "PartitionRecord: Seek misc to specific offset failed", fd, return false); if (offset_ + sizeof(PartitionRecordInfo) < PARTITION_UPDATER_RECORD_SIZE) { + UPDATE_CHECK_FILE_OP(memset_s(&info_, sizeof(info_), 0, sizeof(info_)) == 0, + "PartitionRecord: clear partition info failed", fd, return false); UPDATER_CHECK_FILE_OP(!strncpy_s(info_.partitionName, PARTITION_NAME_LEN, partitionName.c_str(), PARTITION_NAME_LEN - 1), "PartitionRecord: strncpy_s failed", fd, return false); info_.updated = updated; @@ -85,7 +87,7 @@ bool PartitionRecord::RecordPartitionUpdateStatus(const std::string &partitionNa UPDATER_CHECK_FILE_OP(lseek(fd, PARTITION_RECORD_OFFSET, SEEK_SET) >= 0, "PartitionRecord: Seek misc to record offset failed", fd, return false); UPDATER_CHECK_FILE_OP(write(fd, &offset_, sizeof(off_t)) == sizeof(off_t), - "PartitionRecord: Seek misc to record offset failed", fd, return false); + "PartitionRecord: write misc to record offset failed", fd, return false); LOG(DEBUG) << "PartitionRecord: offset is " << offset_; } else { LOG(WARNING) << "PartitionRecord: partition record overflow, offset = " << offset_; diff --git a/services/diffpatch/bzip2/zip_adapter.h b/services/diffpatch/bzip2/zip_adapter.h index 4385bf19..090bddef 100644 --- a/services/diffpatch/bzip2/zip_adapter.h +++ b/services/diffpatch/bzip2/zip_adapter.h @@ -40,7 +40,7 @@ public: private: std::vector buffer_ {}; UpdatePatchWriterPtr outStream_; - z_stream zstream_; + z_stream zstream_ {0}; size_t offset_; int32_t level_ {0}; diff --git a/services/fs_manager/mount.cpp b/services/fs_manager/mount.cpp index 1053f2fa..20f99e76 100644 --- a/services/fs_manager/mount.cpp +++ b/services/fs_manager/mount.cpp @@ -143,7 +143,7 @@ static MountStatus GetMountStatusForMountPoint(const std::string &mountPoint) while (fgets(buffer, sizeof(buffer) - 1, fp.get()) != nullptr) { n = strlen(buffer); - if (buffer[n - 1] == '\n') { + if (n > 0 && buffer[n - 1] == '\n') { buffer[n - 1] = '\0'; } std::string line(buffer); diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 648719ac..20119428 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -19,7 +19,7 @@ #include "securec.h" namespace updater { -void DrmDriver::FlipBuffer(void *buf) +void DrmDriver::FlipBuffer(const void *buf) { if (!buf) { LOG(ERROR) << "buf is null"; diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h index d12b6742..1e074929 100644 --- a/services/ui/drm_driver.h +++ b/services/ui/drm_driver.h @@ -42,7 +42,7 @@ class DrmDriver { protected: DrmDriver() : fd_(-1), conn_(nullptr), res_(nullptr) {} virtual ~DrmDriver(); - void FlipBuffer(void* buf); + void FlipBuffer(const void* buf); void LoadDrmDriver(); private: int ModesetCreateFb(struct BufferObject *bo); diff --git a/services/ui/view.h b/services/ui/view.h index afde4bd4..4fc5152d 100644 --- a/services/ui/view.h +++ b/services/ui/view.h @@ -68,11 +68,11 @@ public: int viewWidth_ = 0; int viewHeight_ = 0; std::mutex mutex_; + char* viewBuffer_ = nullptr; + char* shadowBuffer_ = nullptr; protected: void* CreateBuffer(int w, int h, int pixelFormat); private: - char* viewBuffer_ = nullptr; - char* shadowBuffer_ = nullptr; int bufferSize_ = 0; bool isVisiable_ = true; int viewId_ = 0; diff --git a/services/updater.cpp b/services/updater.cpp index 94e7afac..f5e66db3 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -332,7 +332,7 @@ UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, const std:: UPDATER_ERROR_CHECK(fromChild != nullptr, "fdopen pipeRead failed", return UPDATE_ERROR); while (fgets(buffer, MAX_BUFFER_SIZE - 1, fromChild) != nullptr) { size_t n = strlen(buffer); - if (buffer[n - 1] == '\n') { + if (n > 0 && buffer[n - 1] == '\n') { buffer[n - 1] = '\0'; } HandleChildOutput(buffer, MAX_BUFFER_SIZE, retryUpdate); diff --git a/services/updater_binary/update_partitions.cpp b/services/updater_binary/update_partitions.cpp index 81f26e8b..93aa52e5 100644 --- a/services/updater_binary/update_partitions.cpp +++ b/services/updater_binary/update_partitions.cpp @@ -48,24 +48,25 @@ int UpdatePartitions::ParsePartitionInfo(const std::string &partitionInfo, Parti return 0; } cJSON* thisPartition = cJSON_GetArrayItem(partitions, i); - UPDATER_ERROR_CHECK(thisPartition != nullptr, "Error get thisPartion", free(myPartition); break); + UPDATER_ERROR_CHECK(thisPartition != nullptr, "Error get thisPartion", free(myPartition); + myPartition = nullptr, break); cJSON* item = cJSON_GetObjectItem(thisPartition, "start"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get start", free(myPartition); break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get start", free(myPartition); myPartition = nullptr, break); myPartition->start = item->valueint; item = cJSON_GetObjectItem(thisPartition, "length"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get length", free(myPartition); break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get length", free(myPartition); myPartition = nullptr, break); myPartition->length = item->valueint; myPartition->partNum = 0; myPartition->devName = "mmcblk0px"; item = cJSON_GetObjectItem(thisPartition, "partName"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get partName", free(myPartition); break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get partName", free(myPartition); myPartition = nullptr, break); myPartition->partName = (item->valuestring); item = cJSON_GetObjectItem(thisPartition, "fsType"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get fsType", free(myPartition); break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get fsType", free(myPartition); myPartition = nullptr, break); myPartition->fsType = (item->valuestring); LOG(INFO) << " "; diff --git a/utils/utils.cpp b/utils/utils.cpp index 52c0b201..e9684073 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -162,17 +162,18 @@ std::string ConvertSha256Hex(const uint8_t* shaDigest, size_t length) void DoReboot(const std::string& rebootTarget) { LOG(INFO) << ", rebootTarget: " << rebootTarget; - static const int32_t maxCommandSize = 16; LoadFstab(); auto miscBlockDevice = GetBlockDeviceByMountPoint("/misc"); struct UpdateMessage msg; if (rebootTarget == "updater") { + std::string command = "boot_updater"; bool ret = ReadUpdaterMessage(miscBlockDevice, msg); UPDATER_ERROR_CHECK(ret == true, "DoReboot read misc failed", return); - if (strcmp(msg.command, "boot_updater") != 0) { - UPDATER_ERROR_CHECK(!memcpy_s(msg.command, maxCommandSize, "boot_updater", maxCommandSize - 1), + if (strcmp(msg.command, command.c_str()) != 0) { + UPDATE_ERROR_CHECK(memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE) == 0, + "Failed to clear update message", return); + UPDATER_ERROR_CHECK(!memcpy_s(msg.command, MAX_COMMAND_SIZE - 1, command.c_str(), command.size()), "Memcpy failed", return); - msg.command[maxCommandSize] = 0; } ret = WriteUpdaterMessage(miscBlockDevice, msg); if (ret != true) { -- Gitee From 51210dd0a19a33dc2fc1c04d2ad21e2bf24c2a12 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Thu, 16 Sep 2021 13:48:28 +0000 Subject: [PATCH 16/94] fix codestyle Signed-off-by: ma_nan --- services/applypatch/partition_record.cpp | 2 +- services/updater_binary/update_partitions.cpp | 10 +++++----- utils/utils.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/services/applypatch/partition_record.cpp b/services/applypatch/partition_record.cpp index 79a019d3..e6de89be 100644 --- a/services/applypatch/partition_record.cpp +++ b/services/applypatch/partition_record.cpp @@ -76,7 +76,7 @@ bool PartitionRecord::RecordPartitionUpdateStatus(const std::string &partitionNa UPDATER_CHECK_FILE_OP(lseek(fd, PARTITION_RECORD_START + offset_, SEEK_SET) >= 0, "PartitionRecord: Seek misc to specific offset failed", fd, return false); if (offset_ + sizeof(PartitionRecordInfo) < PARTITION_UPDATER_RECORD_SIZE) { - UPDATE_CHECK_FILE_OP(memset_s(&info_, sizeof(info_), 0, sizeof(info_)) == 0, + UPDATER_CHECK_FILE_OP(memset_s(&info_, sizeof(info_), 0, sizeof(info_)) == 0, "PartitionRecord: clear partition info failed", fd, return false); UPDATER_CHECK_FILE_OP(!strncpy_s(info_.partitionName, PARTITION_NAME_LEN, partitionName.c_str(), PARTITION_NAME_LEN - 1), "PartitionRecord: strncpy_s failed", fd, return false); diff --git a/services/updater_binary/update_partitions.cpp b/services/updater_binary/update_partitions.cpp index 93aa52e5..0f431deb 100644 --- a/services/updater_binary/update_partitions.cpp +++ b/services/updater_binary/update_partitions.cpp @@ -49,24 +49,24 @@ int UpdatePartitions::ParsePartitionInfo(const std::string &partitionInfo, Parti } cJSON* thisPartition = cJSON_GetArrayItem(partitions, i); UPDATER_ERROR_CHECK(thisPartition != nullptr, "Error get thisPartion", free(myPartition); - myPartition = nullptr, break); + myPartition = nullptr; break); cJSON* item = cJSON_GetObjectItem(thisPartition, "start"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get start", free(myPartition); myPartition = nullptr, break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get start", free(myPartition); myPartition = nullptr; break); myPartition->start = item->valueint; item = cJSON_GetObjectItem(thisPartition, "length"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get length", free(myPartition); myPartition = nullptr, break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get length", free(myPartition); myPartition = nullptr; break); myPartition->length = item->valueint; myPartition->partNum = 0; myPartition->devName = "mmcblk0px"; item = cJSON_GetObjectItem(thisPartition, "partName"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get partName", free(myPartition); myPartition = nullptr, break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get partName", free(myPartition); myPartition = nullptr; break); myPartition->partName = (item->valuestring); item = cJSON_GetObjectItem(thisPartition, "fsType"); - UPDATER_ERROR_CHECK(item != nullptr, "Error get fsType", free(myPartition); myPartition = nullptr, break); + UPDATER_ERROR_CHECK(item != nullptr, "Error get fsType", free(myPartition); myPartition = nullptr; break); myPartition->fsType = (item->valuestring); LOG(INFO) << " "; diff --git a/utils/utils.cpp b/utils/utils.cpp index e9684073..285c56fc 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -170,7 +170,7 @@ void DoReboot(const std::string& rebootTarget) bool ret = ReadUpdaterMessage(miscBlockDevice, msg); UPDATER_ERROR_CHECK(ret == true, "DoReboot read misc failed", return); if (strcmp(msg.command, command.c_str()) != 0) { - UPDATE_ERROR_CHECK(memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE) == 0, + UPDATER_ERROR_CHECK(memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE) == 0, "Failed to clear update message", return); UPDATER_ERROR_CHECK(!memcpy_s(msg.command, MAX_COMMAND_SIZE - 1, command.c_str(), command.size()), "Memcpy failed", return); -- Gitee From 256508990fbc96aba57f3298ae2ec40c53e5f52a Mon Sep 17 00:00:00 2001 From: ma_nan Date: Fri, 17 Sep 2021 11:10:03 +0000 Subject: [PATCH 17/94] fix codestyle Signed-off-by: ma_nan --- .../script/script_interpreter/script_expression.cpp | 12 +----------- .../script/script_interpreter/script_expression.h | 1 - .../script/script_interpreter/script_interpreter.cpp | 12 ++++++++++++ .../script/script_interpreter/script_interpreter.h | 6 ++++-- services/ui/drm_driver.cpp | 2 +- services/ui/drm_driver.h | 2 +- services/ui/view.h | 4 ++-- 7 files changed, 21 insertions(+), 18 deletions(-) diff --git a/services/script/script_interpreter/script_expression.cpp b/services/script/script_interpreter/script_expression.cpp index d3f6293b..048d1b38 100644 --- a/services/script/script_interpreter/script_expression.cpp +++ b/services/script/script_interpreter/script_expression.cpp @@ -154,16 +154,7 @@ UScriptValuePtr FunctionCallExpression::Execute(ScriptInterpreter &inter, UScrip if (inter.IsNativeFunction(functionName_)) { return inter.ExecuteNativeFunc(local, functionName_, params_); } - - ScriptFunction* function = function_; - if (function_ == nullptr) { - function = inter.FindFunction(functionName_); - } - if (function == nullptr) { - INTERPRETER_LOGI(inter, local, "Can not find function %s", functionName_.c_str()); - return std::make_shared(USCRIPT_NOTEXIST_INSTRUCTION); - } - return function->Execute(inter, local, params_); + return inter.ExecuteFunction(local, functionName_, params_); } BinaryExpression::~BinaryExpression() @@ -177,7 +168,6 @@ AssignExpression::~AssignExpression() } FunctionCallExpression::~FunctionCallExpression() { - delete function_; delete params_; } } // namespace uscript diff --git a/services/script/script_interpreter/script_expression.h b/services/script/script_interpreter/script_expression.h index c864969c..1d4e163f 100644 --- a/services/script/script_interpreter/script_expression.h +++ b/services/script/script_interpreter/script_expression.h @@ -200,7 +200,6 @@ public: static UScriptExpression* CreateExpression(std::string identifier, ScriptParams *params); private: std::string functionName_; - ScriptFunction* function_ = nullptr; ScriptParams* params_ = nullptr; }; } // namespace uscript diff --git a/services/script/script_interpreter/script_interpreter.cpp b/services/script/script_interpreter/script_interpreter.cpp index bef46fa8..9afdcf9a 100644 --- a/services/script/script_interpreter/script_interpreter.cpp +++ b/services/script/script_interpreter/script_interpreter.cpp @@ -109,6 +109,18 @@ ScriptFunction* ScriptInterpreter::FindFunction(const std::string &name) return nullptr; } +UScriptValuePtr ScriptInterpreter::ExecuteFunction(UScriptContextPtr context, const std::string &name, + ScriptParams *params) +{ + ScriptFunction* function = FindFunction(name); + if (function == nullptr) { + USCRIPT_LOGI("Fail to find function %s", name.c_str()); + return std::make_shared(USCRIPT_NOTEXIST_INSTRUCTION); + } else { + return function->Execute(*this, context, params); + } +} + UScriptValuePtr ScriptInterpreter::FindVariable(UScriptContextPtr local, std::string id) { for (auto context = contextStack_.rbegin(); context != contextStack_.rend(); context++) { diff --git a/services/script/script_interpreter/script_interpreter.h b/services/script/script_interpreter/script_interpreter.h index 7a30b0a1..adced81b 100644 --- a/services/script/script_interpreter/script_interpreter.h +++ b/services/script/script_interpreter/script_interpreter.h @@ -49,10 +49,11 @@ public: void AddStatement(UScriptStatement *statement); int32_t AddFunction(ScriptFunction *function); - ScriptFunction* FindFunction(const std::string &name); bool IsNativeFunction(std::string name); UScriptValuePtr ExecuteNativeFunc(UScriptContextPtr upContext, const std::string &name, ScriptParams *params); + UScriptValuePtr ExecuteFunction(UScriptContextPtr context, const std::string &name, + ScriptParams *params); UScriptValuePtr FindVariable(UScriptContextPtr local, std::string id); UScriptValuePtr UpdateVariable(UScriptContextPtr local, std::string id, UScriptValuePtr var); int32_t GetInstanceId() const @@ -74,6 +75,7 @@ private: int32_t Execute(); private: + ScriptFunction* FindFunction(const std::string &name); UScriptStatementList* statements_ = nullptr; std::map functions_; std::vector contextStack_; @@ -83,4 +85,4 @@ private: int32_t instanceId_ = 0; }; } // namespace uscript -#endif \ No newline at end of file +#endif diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 20119428..648719ac 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -19,7 +19,7 @@ #include "securec.h" namespace updater { -void DrmDriver::FlipBuffer(const void *buf) +void DrmDriver::FlipBuffer(void *buf) { if (!buf) { LOG(ERROR) << "buf is null"; diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h index 1e074929..d12b6742 100644 --- a/services/ui/drm_driver.h +++ b/services/ui/drm_driver.h @@ -42,7 +42,7 @@ class DrmDriver { protected: DrmDriver() : fd_(-1), conn_(nullptr), res_(nullptr) {} virtual ~DrmDriver(); - void FlipBuffer(const void* buf); + void FlipBuffer(void* buf); void LoadDrmDriver(); private: int ModesetCreateFb(struct BufferObject *bo); diff --git a/services/ui/view.h b/services/ui/view.h index 4fc5152d..afde4bd4 100644 --- a/services/ui/view.h +++ b/services/ui/view.h @@ -68,11 +68,11 @@ public: int viewWidth_ = 0; int viewHeight_ = 0; std::mutex mutex_; - char* viewBuffer_ = nullptr; - char* shadowBuffer_ = nullptr; protected: void* CreateBuffer(int w, int h, int pixelFormat); private: + char* viewBuffer_ = nullptr; + char* shadowBuffer_ = nullptr; int bufferSize_ = 0; bool isVisiable_ = true; int viewId_ = 0; -- Gitee From 548365598737091d3f5ee17a9896e52d3d5ee5d1 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Fri, 17 Sep 2021 11:58:44 +0000 Subject: [PATCH 18/94] fix codestyle Signed-off-by: ma_nan --- services/script/script_interpreter/script_interpreter.cpp | 2 +- services/ui/drm_driver.cpp | 2 +- services/ui/drm_driver.h | 2 +- services/ui/view.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/script/script_interpreter/script_interpreter.cpp b/services/script/script_interpreter/script_interpreter.cpp index 9afdcf9a..0531a914 100644 --- a/services/script/script_interpreter/script_interpreter.cpp +++ b/services/script/script_interpreter/script_interpreter.cpp @@ -112,7 +112,7 @@ ScriptFunction* ScriptInterpreter::FindFunction(const std::string &name) UScriptValuePtr ScriptInterpreter::ExecuteFunction(UScriptContextPtr context, const std::string &name, ScriptParams *params) { - ScriptFunction* function = FindFunction(name); + ScriptFunction *function = FindFunction(name); if (function == nullptr) { USCRIPT_LOGI("Fail to find function %s", name.c_str()); return std::make_shared(USCRIPT_NOTEXIST_INSTRUCTION); diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 648719ac..20119428 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -19,7 +19,7 @@ #include "securec.h" namespace updater { -void DrmDriver::FlipBuffer(void *buf) +void DrmDriver::FlipBuffer(const void *buf) { if (!buf) { LOG(ERROR) << "buf is null"; diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h index d12b6742..1e074929 100644 --- a/services/ui/drm_driver.h +++ b/services/ui/drm_driver.h @@ -42,7 +42,7 @@ class DrmDriver { protected: DrmDriver() : fd_(-1), conn_(nullptr), res_(nullptr) {} virtual ~DrmDriver(); - void FlipBuffer(void* buf); + void FlipBuffer(const void* buf); void LoadDrmDriver(); private: int ModesetCreateFb(struct BufferObject *bo); diff --git a/services/ui/view.h b/services/ui/view.h index afde4bd4..0f8fa7e0 100644 --- a/services/ui/view.h +++ b/services/ui/view.h @@ -70,9 +70,9 @@ public: std::mutex mutex_; protected: void* CreateBuffer(int w, int h, int pixelFormat); -private: char* viewBuffer_ = nullptr; char* shadowBuffer_ = nullptr; +private: int bufferSize_ = 0; bool isVisiable_ = true; int viewId_ = 0; -- Gitee From 98f4d950fe06be87671d28ae0f2ab07bc7f84121 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Fri, 17 Sep 2021 12:11:04 +0000 Subject: [PATCH 19/94] fix codestyle Signed-off-by: ma_nan --- utils/utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/utils.cpp b/utils/utils.cpp index 285c56fc..84b21d20 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -166,7 +166,7 @@ void DoReboot(const std::string& rebootTarget) auto miscBlockDevice = GetBlockDeviceByMountPoint("/misc"); struct UpdateMessage msg; if (rebootTarget == "updater") { - std::string command = "boot_updater"; + std::string command = "boot_updater"; bool ret = ReadUpdaterMessage(miscBlockDevice, msg); UPDATER_ERROR_CHECK(ret == true, "DoReboot read misc failed", return); if (strcmp(msg.command, command.c_str()) != 0) { -- Gitee From 5b6c7fdcb574b90ec6cf6306a04a73e0f5299746 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Tue, 28 Sep 2021 22:15:02 +0800 Subject: [PATCH 20/94] fix ut codestyle Signed-off-by: ma_nan --- .../applypatch_test/all_cmd_unittest.cpp | 4 +-- .../applypatch_test/applypatch_unittest.cpp | 10 ++++-- .../applypatch_test/blockset_unittest.cpp | 10 ++++++ .../applypatch_test/commands_unittest.cpp | 2 ++ .../applypatch_test/imagepatch_unittest.cpp | 1 + .../applypatch_test/imagepatch_unittest.h | 2 +- .../misc_info_test/misc_info_unittest.cpp | 9 ++--- test/unittest/mount_test/mount_unittest.cpp | 3 +- .../unittest/package/pkg_manager_unittest.cpp | 8 ++--- .../script/script_interpreter_unittest.cpp | 10 +++--- .../update_processor_unittest.cpp | 5 +++ .../updater_main_unittest.cpp | 33 +++++++++++-------- 12 files changed, 63 insertions(+), 34 deletions(-) diff --git a/test/unittest/applypatch_test/all_cmd_unittest.cpp b/test/unittest/applypatch_test/all_cmd_unittest.cpp index 5e712fa2..489b5b26 100755 --- a/test/unittest/applypatch_test/all_cmd_unittest.cpp +++ b/test/unittest/applypatch_test/all_cmd_unittest.cpp @@ -176,11 +176,11 @@ HWTEST_F(AllCmdUnitTest, allCmd_test_002, TestSize.Level1) utils::MkdirRecursive(TransferManager::GetTransferManagerInstance()->GetGlobalParams()->storeBase, dirMode); std::vector buffer(bufferSize, 0); int fd = open(filePath.c_str(), O_RDWR | O_CREAT, dirMode); - lseek64(fd, 0, SEEK_SET); - if (fd == -1) { + if (fd < 0) { printf("Failed to open block %s, errno: %d\n", filePath.c_str(), errno); return; } + lseek64(fd, 0, SEEK_SET); auto res = WriteTestBin(fd, *buffer.data(), bufferSize * count); if (!res) { printf("Write to bin error\n"); diff --git a/test/unittest/applypatch_test/applypatch_unittest.cpp b/test/unittest/applypatch_test/applypatch_unittest.cpp index 6cc31833..4f70a0ef 100755 --- a/test/unittest/applypatch_test/applypatch_unittest.cpp +++ b/test/unittest/applypatch_test/applypatch_unittest.cpp @@ -92,7 +92,7 @@ HWTEST_F(ApplyPatchUnitTest, updater_RawWriter, TestSize.Level1) EXPECT_TRUE(ret); int fd = open(devPath.c_str(), O_RDONLY); - EXPECT_GT(fd, 0); + EXPECT_GE(fd, 0); uint8_t buffer[BUFFER_LEN + 1] = {0}; size_t n = read(fd, buffer, BUFFER_LEN); @@ -116,7 +116,13 @@ HWTEST_F(ApplyPatchUnitTest, updater_DataWriterOpenPartition, TestSize.Level1) partitionName = "/rawwriter"; auto devPath = GetBlockDeviceByMountPoint(partitionName); - close(open(devPath.c_str(), O_CREAT | O_WRONLY | O_EXCL, 0664)); + int fd = open(devPath.c_str(), O_CREAT | O_WRONLY | O_EXCL, 0664); + if (fd < 0) { + printf("Open %s failed", devPath.c_str()); + FAIL(); + return; + } + close(fd); writer = DataWriter::CreateDataWriter(mode, partitionName); EXPECT_NE(writer, nullptr); ret = writer->OpenPartition(partitionName); diff --git a/test/unittest/applypatch_test/blockset_unittest.cpp b/test/unittest/applypatch_test/blockset_unittest.cpp index 6d948e84..866765b2 100755 --- a/test/unittest/applypatch_test/blockset_unittest.cpp +++ b/test/unittest/applypatch_test/blockset_unittest.cpp @@ -87,7 +87,12 @@ HWTEST_F(BlockSetUnitTest, blockset_test_003, TestSize.Level1) std::fill(buffer.begin(), buffer.end(), 0); std::string filename = "/tmp/ut_blockset"; int fd = open(filename.c_str(), O_RDWR); + if (fd < 0) { + printf("Open file failed"); + return; + } blk.WriteDataToBlock(fd, buffer); + close(fd); } HWTEST_F(BlockSetUnitTest, blockset_test_004, TestSize.Level1) @@ -109,6 +114,10 @@ HWTEST_F(BlockSetUnitTest, blockset_test_005, TestSize.Level1) std::string blockInfo = "2,20755,21031 276 2,20306,20582"; std::string cmdLine = std::string("move ") + hashValue + " " + blockInfo; int fd = open("/data/updater/updater/blocksetTest.txt", O_CREAT | O_WRONLY, S_IRWXU | S_IRWXG | S_IRWXO); + if (fd < 0) { + printf("Open file failed"); + return; + } Command *cmd = new Command(); cmd->Init(cmdLine); cmd->SetFileDescriptor(fd); @@ -122,5 +131,6 @@ HWTEST_F(BlockSetUnitTest, blockset_test_005, TestSize.Level1) ret = targetBlock.WriteDiffToBlock(const_cast(*cmd), buffer, tgtBlockSize, isImgDiff); EXPECT_EQ(ret, -1); close(fd); + delete cmd; } } diff --git a/test/unittest/applypatch_test/commands_unittest.cpp b/test/unittest/applypatch_test/commands_unittest.cpp index 59249952..809d669b 100755 --- a/test/unittest/applypatch_test/commands_unittest.cpp +++ b/test/unittest/applypatch_test/commands_unittest.cpp @@ -62,6 +62,7 @@ HWTEST_F(CommandsUnitTest, command_test_001, TestSize.Level0) sha256 = cmd->GetArgumentByPos(1); EXPECT_EQ(sha256, "5aa246ebe8e817740f12cc0f6e536c5ea22e5db177563a1caea5a86614275546"); EXPECT_EQ(cmd->GetCommandLine(), cmdLine); + delete cmd; } HWTEST_F(CommandsUnitTest, command_test_002, TestSize.Level0) @@ -91,5 +92,6 @@ HWTEST_F(CommandsUnitTest, command_test_002, TestSize.Level0) EXPECT_EQ(cmd->Init(cmdLine), true); cmdLine = "last 1,1"; EXPECT_EQ(cmd->Init(cmdLine), true); + delete cmd; } } // updater_ut diff --git a/test/unittest/applypatch_test/imagepatch_unittest.cpp b/test/unittest/applypatch_test/imagepatch_unittest.cpp index 71388147..c9a1466c 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.cpp +++ b/test/unittest/applypatch_test/imagepatch_unittest.cpp @@ -53,6 +53,7 @@ bool ImagePatchTest::ReadContentFromFile(const std::string& file, std::string &c while ((n = read(fd, buffer, sizeof(buffer))) > 0) { content.append(buffer, n); } + close(fd); return ((n == 0) ? true : false); } diff --git a/test/unittest/applypatch_test/imagepatch_unittest.h b/test/unittest/applypatch_test/imagepatch_unittest.h index efff589c..6da5f553 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.h +++ b/test/unittest/applypatch_test/imagepatch_unittest.h @@ -75,7 +75,7 @@ public: { mode_t mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); int fd = open(target.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY, mode); - EXPECT_GT(fd, 0); + EXPECT_GE(fd, 0); BlockSet targetBlk; targetBlk.ParserAndInsert({ "2", "0", "1" diff --git a/test/unittest/misc_info_test/misc_info_unittest.cpp b/test/unittest/misc_info_test/misc_info_unittest.cpp index dd3b1545..0895b703 100755 --- a/test/unittest/misc_info_test/misc_info_unittest.cpp +++ b/test/unittest/misc_info_test/misc_info_unittest.cpp @@ -42,10 +42,11 @@ HWTEST_F(MiscInfoUnitTest, misc_info_test_001, TestSize.Level1) auto fp = std::unique_ptr(fopen(MISC_FILE.c_str(), "wb"), fclose); EXPECT_NE(fp, nullptr); - UpdateMessage boot {}; - EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command), "boot_updater", sizeof(boot.command)), 0); - EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), - "--update_package=./updater/xxx.zip\n--retry_count=1", sizeof(boot.update)), 0); + UpdateMessage boot {}; + const std::string command1 = "boot_updater"; + EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command) - 1, command1.c_str(), command1.size()), 0); + const std::string command2 = "--update_package=./updater/xxx.zip\n--retry_count=1"; + EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update) - 1, command2.c_str(), command2.size()), 0); bool ret = WriteUpdaterMessage(MISC_FILE, boot); EXPECT_EQ(ret, true); diff --git a/test/unittest/mount_test/mount_unittest.cpp b/test/unittest/mount_test/mount_unittest.cpp index 832a936d..80f80b8d 100755 --- a/test/unittest/mount_test/mount_unittest.cpp +++ b/test/unittest/mount_test/mount_unittest.cpp @@ -177,8 +177,9 @@ HWTEST_F(MountUnitTest, GetBlockDeviceByMountPoint_unitest, TestSize.Level1) std::cout << "Cannot re-mount vendor\n"; } auto ret = open(tmpPath.c_str(), O_RDONLY|O_CREAT|O_TRUNC, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - if (ret != 0 && errno != EEXIST) { + if (ret < 0) { std::cout << "Cannot open \"/vendor/etc/fstab.updater\" file: " << errno << "\n"; + return; } close(ret); LoadFstab(); diff --git a/test/unittest/package/pkg_manager_unittest.cpp b/test/unittest/package/pkg_manager_unittest.cpp index 54bb964a..d968d701 100755 --- a/test/unittest/package/pkg_manager_unittest.cpp +++ b/test/unittest/package/pkg_manager_unittest.cpp @@ -528,7 +528,6 @@ public: (void)start; (void)buffer; size_t oldSize = uncompressedData.size(); - PKG_CHECK(oldSize != 0, return -1, "oldSize is 0"); if ((start + size) > uncompressedData.size()) { uncompressedData.resize(oldSize * ((start + size) / oldSize + 1)); } @@ -540,7 +539,7 @@ public: [&](hpackage::PkgManager::StreamPtr stream) { pkgManager_->ClosePkgStream(stream); }); - PKG_CHECK(outStream != nullptr, return -1, "Can not create stream "); + PKG_CHECK(outStream != nullptr, close(fd); return -1, "Can not create stream "); void* mappedData = mmap(nullptr, (size_t)fileSize, PROT_READ, MAP_SHARED, fd, 0); PKG_CHECK(mappedData != MAP_FAILED, close(fd); return -2, "Can not mmap "); @@ -608,7 +607,7 @@ public: size_t fileSize = GetFileSize(testFileName); size_t uncompressedDataSize = 1024; int32_t fd = open(testFileName.c_str(), O_RDWR); - EXPECT_GT(fd, 0); + EXPECT_GE(fd, 0); uncompressedData.resize(uncompressedDataSize); PkgManager::StreamPtr stream = nullptr; @@ -620,7 +619,6 @@ public: (void)start; (void)buffer; size_t oldSize = uncompressedData.size(); - PKG_CHECK(oldSize != 0, return -1, "oldSize is 0"); if ((start + size) > uncompressedData.size()) { uncompressedData.resize(oldSize * ((start + size) / oldSize + 1)); } @@ -632,7 +630,7 @@ public: [&](hpackage::PkgManager::StreamPtr stream) { pkgManager_->ClosePkgStream(stream); }); - PKG_CHECK(outStream != nullptr, return -1, "Can not create stream "); + PKG_CHECK(outStream != nullptr, close(fd); return -1, "Can not create stream "); void* mappedData = mmap(nullptr, (size_t)fileSize, PROT_READ, MAP_SHARED, fd, 0); PKG_CHECK(mappedData != MAP_FAILED, close(fd); return -2, "Can not mmap "); diff --git a/test/unittest/script/script_interpreter_unittest.cpp b/test/unittest/script/script_interpreter_unittest.cpp index db031a77..29081914 100755 --- a/test/unittest/script/script_interpreter_unittest.cpp +++ b/test/unittest/script/script_interpreter_unittest.cpp @@ -101,15 +101,15 @@ public: { std::unique_ptr funcContext = std::make_unique(); int intValue = 100; - int ret = funcContext->PushParam(intValue); + int ret1 = funcContext->PushParam(intValue); float floatValue = 100.0; - ret |= funcContext->PushParam(floatValue); + int ret2 = funcContext->PushParam(floatValue); std::string str = std::string("333333333"); - ret |= funcContext->PushParam(str); - EXPECT_EQ(0, ret); + int ret3 = funcContext->PushParam(str); + EXPECT_EQ(0, ret1 || ret2 || ret3); int32_t outOfIndex = 3; - ret = funcContext->GetParamType(outOfIndex); + int ret = funcContext->GetParamType(outOfIndex); EXPECT_EQ(UScriptContext::PARAM_TYPE_INVALID, ret); return 0; } diff --git a/test/unittest/updater_binary/update_processor_unittest.cpp b/test/unittest/updater_binary/update_processor_unittest.cpp index d8ff4857..e86e72ee 100755 --- a/test/unittest/updater_binary/update_processor_unittest.cpp +++ b/test/unittest/updater_binary/update_processor_unittest.cpp @@ -72,6 +72,11 @@ HWTEST_F(UpdateProcessorUnitTest, UpdateProcessor_001, TestSize.Level1) updater::utils::MkdirRecursive(devDir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); int fd = open(devPath.c_str(), O_CREAT | O_WRONLY | O_EXCL, 0664); printf("@@@ devPath = %s, fd=%d\n", devPath.c_str(), fd); + if (fd < 0) { + printf("Open failed, fd = %d", fd); + FAIL(); + return; + } close(fd); for (int32_t i = 0; i < ScriptManager::MAX_PRIORITY; i++) { diff --git a/test/unittest/updater_main_test/updater_main_unittest.cpp b/test/unittest/updater_main_test/updater_main_unittest.cpp index 9f2dad4b..a13bcbb5 100755 --- a/test/unittest/updater_main_test/updater_main_unittest.cpp +++ b/test/unittest/updater_main_test/updater_main_unittest.cpp @@ -26,7 +26,7 @@ #include "updater_ui.h" #include "utils.h" -using namespace updater; +using namespace updater; using namespace testing::ext; using namespace std; using namespace updater::utils; @@ -76,7 +76,8 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_001, TestSize.Level1) const std::string commandFile = "/data/updater/command"; auto fp = std::unique_ptr(fopen(commandFile.c_str(), "wb"), fclose); EXPECT_NE(fp, nullptr); - EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command), "boot_updater", sizeof(boot.command)), 0); + const std::string commandMsg = "boot_updater"; + EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command) - 1, commandMsg.c_str(), commandMsg.size()), 0); EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "", sizeof(boot.update)), 0); bool bRet = WriteUpdaterMessage(commandFile, boot); EXPECT_EQ(bRet, true); @@ -95,8 +96,10 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_001, TestSize.Level1) HWTEST_F(UpdaterMainUnitTest, updater_main_test_002, TestSize.Level1) { UpdateMessage boot {}; - EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command), "boot_updater", sizeof(boot.command)), 0); - EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "--user_wipe_data", sizeof(boot.update)), 0); + const std::string command1 = "boot_updater"; + EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command) - 1, command1.c_str(), command1.size()), 0); + const std::string command2 = "--user_wipe_data"; + EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update) - 1, command2.c_str(), command2.size()), 0); bool ret = WriteUpdaterMessage(MISC_FILE, boot); EXPECT_EQ(ret, true); @@ -114,7 +117,6 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_003, TestSize.Level1) unlink(dLog.c_str()); } - HWTEST_F(UpdaterMainUnitTest, updater_main_test_004, TestSize.Level1) { UpdaterUiInit(); @@ -122,25 +124,29 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_004, TestSize.Level1) EXPECT_NE(fp, nullptr); UpdateMessage boot {}; - EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command), "boot_updater", sizeof(boot.command)), 0); - EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), - "--update_package=/data/updater/updater.zip\n--retry_count=0", sizeof(boot.update)), 0); + const std::string command1 = "boot_updater"; + EXPECT_EQ(strncpy_s(boot.command, sizeof(boot.command) - 1, command1.c_str(), command1.size()), 0); + const std::string command2 = "--update_package=/data/updater/updater.zip\n--retry_count=0"; + EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update) - 1, command2.c_str(), command2.size()), 0); bool ret = WriteUpdaterMessage(MISC_FILE, boot); EXPECT_EQ(ret, true); - - int lRet = 0; - int argc = 1; + + int lRet = 0; + int argc = 1; char **argv = new char*[MAX_ARG_SIZE]; argv[0] = new char[10]; + EXPECT_EQ(memset_s(boot.update, sizeof(boot.update), 0, sizeof(boot.update)), 0); - EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "--user_wipe_data", sizeof(boot.update)), 0); + const std::string command3 = "--user_wipe_data"; + EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update) - 1, command3.c_str(), command3.size()), 0); ret = WriteUpdaterMessage(MISC_FILE, boot); EXPECT_EQ(ret, true); lRet = UpdaterMain(argc, argv); EXPECT_EQ(lRet, 0); EXPECT_EQ(memset_s(boot.update, sizeof(boot.update), 0, sizeof(boot.update)), 0); - EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update), "--factory_wipe_data", sizeof(boot.update)), 0); + const std::string command4 = "--factory_wipe_data"; + EXPECT_EQ(strncpy_s(boot.update, sizeof(boot.update) - 1, command4.c_str(), command4.size()), 0); ret = WriteUpdaterMessage(MISC_FILE, boot); EXPECT_EQ(ret, true); lRet = UpdaterMain(argc, argv); @@ -154,7 +160,6 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_004, TestSize.Level1) DeleteView(); } - HWTEST_F(UpdaterMainUnitTest, updater_main_test_compress, TestSize.Level1) { const std::string testFile = "/data/sdcard/updater/test_compress.txt"; -- Gitee From ab4fc9bbc955c7909c40db015da727ba318a3dbf Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 29 Sep 2021 19:41:12 +0800 Subject: [PATCH 21/94] fix ut codestyle Signed-off-by: ma_nan --- OAT.xml | 18 +++++++++++---- services/package/pkg_package/pkg_pkgfile.cpp | 2 -- .../applypatch_test/imagepatch_unittest.cpp | 9 ++++---- .../fs_manager/do_partition_unittest.cpp | 4 ++-- test/unittest/package/pkg_algo_unittest.cpp | 4 ++-- .../unittest/package/pkg_manager_unittest.cpp | 23 +++++++++++++------ test/unittest/package/pkg_test.h | 1 + test/unittest/script/script_unittest.cpp | 3 ++- .../updater_binary_unittest.cpp | 19 +++++++++++---- .../updater_main_unittest.cpp | 2 +- 10 files changed, 56 insertions(+), 29 deletions(-) diff --git a/OAT.xml b/OAT.xml index e52288de..e308ba55 100755 --- a/OAT.xml +++ b/OAT.xml @@ -65,14 +65,22 @@ Note:If the text contains special characters, please escape them according to th - + - - - - + + + + + + + + + + + + diff --git a/services/package/pkg_package/pkg_pkgfile.cpp b/services/package/pkg_package/pkg_pkgfile.cpp index afa0724d..5deac71e 100644 --- a/services/package/pkg_package/pkg_pkgfile.cpp +++ b/services/package/pkg_package/pkg_pkgfile.cpp @@ -34,8 +34,6 @@ PkgFile::~PkgFile() } pkgEntryMapId_.clear(); pkgEntryMapFileName_.clear(); - PkgManager::StreamPtr tmpStream = pkgStream_; - PkgManager::GetPackageInstance()->ClosePkgStream(tmpStream); } PkgEntryPtr PkgFile::AddPkgEntry(const std::string &fileName) diff --git a/test/unittest/applypatch_test/imagepatch_unittest.cpp b/test/unittest/applypatch_test/imagepatch_unittest.cpp index c9a1466c..15126bf3 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.cpp +++ b/test/unittest/applypatch_test/imagepatch_unittest.cpp @@ -53,7 +53,6 @@ bool ImagePatchTest::ReadContentFromFile(const std::string& file, std::string &c while ((n = read(fd, buffer, sizeof(buffer))) > 0) { content.append(buffer, n); } - close(fd); return ((n == 0) ? true : false); } @@ -73,7 +72,7 @@ int ImagePatchTest::TestZipModeImagePatch() const reinterpret_cast(sourceData.data()), sourceData.size(), reinterpret_cast(patchContent.data()), patchContent.size() }; - return RunImageApplyPatch(param, "out_put_zip.zip", expectedSHA256); + return RunImageApplyPatch(param, "/data/updater/applypatch/out_put_zip.zip", expectedSHA256); } int ImagePatchTest::TestNormalModeImagePatch() const @@ -90,7 +89,7 @@ int ImagePatchTest::TestNormalModeImagePatch() const reinterpret_cast(sourceData.data()), sourceData.size(), reinterpret_cast(patchContent.data()), patchContent.size() }; - return RunImageApplyPatch(param, "out_put_zip.zip", expectedSHA256); + return RunImageApplyPatch(param, "/data/updater/diffpatch/out_put_zip.zip", expectedSHA256); } int ImagePatchTest::TestGZipModeImagePatch() const @@ -106,7 +105,7 @@ int ImagePatchTest::TestGZipModeImagePatch() const reinterpret_cast(sourceData.data()), sourceData.size(), reinterpret_cast(patchContent.data()), patchContent.size() }; - int ret = RunImageApplyPatch(param, "out_put_gzip.gzip", expectedSHA256); + int ret = RunImageApplyPatch(param, "/data/updater/applypatch/out_put_gzip.gzip", expectedSHA256); return ret; } @@ -123,7 +122,7 @@ int ImagePatchTest::TestLZ4ModeImagePatch() const reinterpret_cast(sourceData.data()), sourceData.size(), reinterpret_cast(patchContent.data()), patchContent.size() }; - RunImageApplyPatch(param, "out_put_lz4.lz4", expectedSHA256); + RunImageApplyPatch(param, "/data/updater/diffpatch/out_put_lz4.lz4", expectedSHA256); return 0; } diff --git a/test/unittest/fs_manager/do_partition_unittest.cpp b/test/unittest/fs_manager/do_partition_unittest.cpp index cf0a03d7..672b20bd 100755 --- a/test/unittest/fs_manager/do_partition_unittest.cpp +++ b/test/unittest/fs_manager/do_partition_unittest.cpp @@ -122,8 +122,8 @@ HWTEST_F(DoPartitionUnitTest, do_partition_test_001, TestSize.Level1) int ret1 = RegisterUpdaterPartitionList(nList, olist); ASSERT_EQ(ret1, 1); - char aaa[BUFFER_SIZE]; - BlockDevice myDev; + char aaa[BUFFER_SIZE] = {0}; + BlockDevice myDev {}; myDev.devPath = "xxxxxx"; myDev.specific = (void *)aaa; SetBlockDeviceMode(myDev); diff --git a/test/unittest/package/pkg_algo_unittest.cpp b/test/unittest/package/pkg_algo_unittest.cpp index e78461bb..fbab4b1c 100755 --- a/test/unittest/package/pkg_algo_unittest.cpp +++ b/test/unittest/package/pkg_algo_unittest.cpp @@ -252,9 +252,9 @@ HWTEST_F(PkgAlgoUnitTest, TestInvalid, TestSize.Level1) HWTEST_F(PkgAlgoUnitTest, TestPkgAlgoDeflate, TestSize.Level1) { - ZipFileInfo info; + ZipFileInfo info {}; PkgAlgoDeflate a1(info); - Lz4FileInfo config; + Lz4FileInfo config {}; PkgAlgorithmLz4 a2(config); PkgAlgorithmBlockLz4 a3(config); VerifyAlgorithm a4("aa", 0); diff --git a/test/unittest/package/pkg_manager_unittest.cpp b/test/unittest/package/pkg_manager_unittest.cpp index d968d701..74034348 100755 --- a/test/unittest/package/pkg_manager_unittest.cpp +++ b/test/unittest/package/pkg_manager_unittest.cpp @@ -73,7 +73,7 @@ public: } const std::string GetFileName() const override { - return 0; + return ""; } size_t GetFileLength() override { @@ -188,7 +188,10 @@ public: // 测试文件提取 PkgManager::StreamPtr outStream = nullptr; const FileInfo *info = pkgManager_->GetFileInfo(components[0]); - EXPECT_NE(info, nullptr); + if (info == nullptr) { + return PKG_INVALID_FILE; + } + ret = pkgManager_->CreatePkgStream(outStream, components[0], info->unpackedSize, PkgStream::PkgStreamType_MemoryMap); EXPECT_NE(outStream, nullptr); @@ -266,7 +269,9 @@ public: // 测试文件提取 PkgManager::StreamPtr outStream = nullptr; const FileInfo *info = pkgManager_->GetFileInfo(components[0]); - EXPECT_NE(info, nullptr); + if (info == nullptr) { + return PKG_INVALID_FILE; + } ret = pkgManager_->CreatePkgStream(outStream, TEST_PATH_TO + components[0], info->unpackedSize, PkgStream::PkgStreamType_Write); @@ -303,7 +308,10 @@ public: // 测试文件提取 PkgManager::StreamPtr outStream = nullptr; const FileInfo *info = pkgManager_->GetFileInfo(components[0]); - EXPECT_NE(info, nullptr); + if (info == nullptr) { + return PKG_INVALID_FILE; + } + ret = pkgManager_->CreatePkgStream(outStream, components[0], TestStreamProcess, this); EXPECT_NE(outStream, nullptr); @@ -606,9 +614,10 @@ public: std::string testFileName = TEST_PATH_FROM + "../applypatch/TestDecompressGzip.new.gz"; size_t fileSize = GetFileSize(testFileName); size_t uncompressedDataSize = 1024; - int32_t fd = open(testFileName.c_str(), O_RDWR); - EXPECT_GE(fd, 0); - + int fd = open(testFileName.c_str(), O_RDWR); + if (fd < 0) { + return -1; + } uncompressedData.resize(uncompressedDataSize); PkgManager::StreamPtr stream = nullptr; pkgManager_->CreatePkgStream(stream, "Gzip", diff --git a/test/unittest/package/pkg_test.h b/test/unittest/package/pkg_test.h index badd45df..16a72a4d 100755 --- a/test/unittest/package/pkg_test.h +++ b/test/unittest/package/pkg_test.h @@ -118,6 +118,7 @@ protected: EXPECT_EQ(ret, 0); manager->ClosePkgStream(outStream); const FileInfo *info = manager->GetFileInfo(components[i]); + ASSERT_NE(info, nullptr); if (info->packMethod == PKG_COMPRESS_METHOD_NONE) { const ComponentInfo* compInfo = (const ComponentInfo*)manager->GetFileInfo(components[i]); if (compInfo != nullptr) { diff --git a/test/unittest/script/script_unittest.cpp b/test/unittest/script/script_unittest.cpp index e8bee2ae..f32fa7e6 100755 --- a/test/unittest/script/script_unittest.cpp +++ b/test/unittest/script/script_unittest.cpp @@ -72,6 +72,7 @@ public: virtual void DestoryInstructionInstance(UScriptInstructionPtr& instr) { delete instr; + instr = nullptr; } TestScriptInstructionFactory() {} virtual ~TestScriptInstructionFactory() {} @@ -108,8 +109,8 @@ public: { return isRetry; } -private: UScriptInstructionFactory *factory_ = nullptr; +private: bool isRetry = false; }; diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index 52fd11f5..76a0a63c 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -129,6 +129,9 @@ protected: ComponentInfoExt *comp = (ComponentInfoExt*)malloc( sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); + if (comp == nullptr) { + return -1; + } for (size_t i = 0; i < testFileNames_.size(); i++) { BuildCompnentInfo(comp[i], testFileNames_[i], testFileNames_[i], componentType); } @@ -149,10 +152,18 @@ protected: free(comp[i].filePath); free(comp[i].version); } - free(pkgInfo.productUpdateId); - free(pkgInfo.softwareVersion); - free(pkgInfo.date); - free(pkgInfo.time); + if (pkgInfo.productUpdateId != nullptr) { + free(pkgInfo.productUpdateId); + } + if (pkgInfo.softwareVersion != nullptr) { + free(pkgInfo.softwareVersion); + } + if (pkgInfo.date != nullptr) { + free(pkgInfo.date); + } + if (pkgInfo.time != nullptr) { + free(pkgInfo.time); + } free(comp); return ret; } diff --git a/test/unittest/updater_main_test/updater_main_unittest.cpp b/test/unittest/updater_main_test/updater_main_unittest.cpp index a13bcbb5..5a696c0a 100755 --- a/test/unittest/updater_main_test/updater_main_unittest.cpp +++ b/test/unittest/updater_main_test/updater_main_unittest.cpp @@ -164,7 +164,7 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_compress, TestSize.Level1) { const std::string testFile = "/data/sdcard/updater/test_compress.txt"; FILE *fp = fopen(testFile.c_str(), "w"); - EXPECT_NE(fp, nullptr); + ASSERT_NE(fp, nullptr); fclose(fp); CompressLogs(testFile); } -- Gitee From 891760aadd361400f1c089985aa3e7edb8099c90 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 29 Sep 2021 19:45:15 +0800 Subject: [PATCH 22/94] fix ut codestyle Signed-off-by: ma_nan --- test/unittest/applypatch_test/imagepatch_unittest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unittest/applypatch_test/imagepatch_unittest.cpp b/test/unittest/applypatch_test/imagepatch_unittest.cpp index 15126bf3..f58c5fd5 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.cpp +++ b/test/unittest/applypatch_test/imagepatch_unittest.cpp @@ -53,6 +53,7 @@ bool ImagePatchTest::ReadContentFromFile(const std::string& file, std::string &c while ((n = read(fd, buffer, sizeof(buffer))) > 0) { content.append(buffer, n); } + close(fd); return ((n == 0) ? true : false); } -- Gitee From 7e574acbc1e4c6a2025a48b04ca45500e0868565 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 29 Sep 2021 19:55:00 +0800 Subject: [PATCH 23/94] fix ut codestyle Signed-off-by: ma_nan --- test/unittest/applypatch_test/store_unittest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unittest/applypatch_test/store_unittest.cpp b/test/unittest/applypatch_test/store_unittest.cpp index 8f683f94..ca635702 100755 --- a/test/unittest/applypatch_test/store_unittest.cpp +++ b/test/unittest/applypatch_test/store_unittest.cpp @@ -62,6 +62,6 @@ HWTEST_F(StoreUnitTest, store_test_002, TestSize.Level1) Store::CreateNewSpace(storePath, true); std::vector buffer(4096, 0); std::string filename1 = "test_file1"; - EXPECT_EQ(Store::WriteDataToStore(storePath, filename1, buffer, -1), -1); + EXPECT_EQ(Store::WriteDataToStore(storePath, filename1, buffer, 0), -1); } } -- Gitee From 23311502e803c10fa3d4b8a270db06fb1247527e Mon Sep 17 00:00:00 2001 From: ma_nan Date: Wed, 29 Sep 2021 20:23:31 +0800 Subject: [PATCH 24/94] fix ut codestyle Signed-off-by: ma_nan --- test/unittest/applypatch_test/store_unittest.cpp | 4 ++-- test/unittest/package/pkg_manager_unittest.cpp | 2 +- test/unittest/updater_binary/updater_binary_unittest.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/unittest/applypatch_test/store_unittest.cpp b/test/unittest/applypatch_test/store_unittest.cpp index ca635702..aa407f3a 100755 --- a/test/unittest/applypatch_test/store_unittest.cpp +++ b/test/unittest/applypatch_test/store_unittest.cpp @@ -58,10 +58,10 @@ HWTEST_F(StoreUnitTest, store_test_001, TestSize.Level1) HWTEST_F(StoreUnitTest, store_test_002, TestSize.Level1) { - std::string storePath = "/data/updater/ut_test"; + std::string storePath = ""; Store::CreateNewSpace(storePath, true); std::vector buffer(4096, 0); std::string filename1 = "test_file1"; - EXPECT_EQ(Store::WriteDataToStore(storePath, filename1, buffer, 0), -1); + EXPECT_EQ(Store::WriteDataToStore(storePath, filename1, buffer, buffer.size()), -1); } } diff --git a/test/unittest/package/pkg_manager_unittest.cpp b/test/unittest/package/pkg_manager_unittest.cpp index 74034348..ec795918 100755 --- a/test/unittest/package/pkg_manager_unittest.cpp +++ b/test/unittest/package/pkg_manager_unittest.cpp @@ -190,7 +190,7 @@ public: const FileInfo *info = pkgManager_->GetFileInfo(components[0]); if (info == nullptr) { return PKG_INVALID_FILE; - } + } ret = pkgManager_->CreatePkgStream(outStream, components[0], info->unpackedSize, PkgStream::PkgStreamType_MemoryMap); diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index 76a0a63c..770adb21 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -131,7 +131,7 @@ protected: sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); if (comp == nullptr) { return -1; - } + } for (size_t i = 0; i < testFileNames_.size(); i++) { BuildCompnentInfo(comp[i], testFileNames_[i], testFileNames_[i], componentType); } @@ -152,7 +152,7 @@ protected: free(comp[i].filePath); free(comp[i].version); } - if (pkgInfo.productUpdateId != nullptr) { + if (pkgInfo.productUpdateId != nullptr) { free(pkgInfo.productUpdateId); } if (pkgInfo.softwareVersion != nullptr) { @@ -161,7 +161,7 @@ protected: if (pkgInfo.date != nullptr) { free(pkgInfo.date); } - if (pkgInfo.time != nullptr) { + if (pkgInfo.time != nullptr) { free(pkgInfo.time); } free(comp); -- Gitee From f0f14459d2490a07c0e2c108633c0db09dbfc234 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Thu, 30 Sep 2021 17:14:39 +0800 Subject: [PATCH 25/94] fix ut codestyle Signed-off-by: ma_nan --- test/unittest/applypatch_test/store_unittest.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/unittest/applypatch_test/store_unittest.cpp b/test/unittest/applypatch_test/store_unittest.cpp index aa407f3a..237ed9e8 100755 --- a/test/unittest/applypatch_test/store_unittest.cpp +++ b/test/unittest/applypatch_test/store_unittest.cpp @@ -58,10 +58,7 @@ HWTEST_F(StoreUnitTest, store_test_001, TestSize.Level1) HWTEST_F(StoreUnitTest, store_test_002, TestSize.Level1) { - std::string storePath = ""; - Store::CreateNewSpace(storePath, true); std::vector buffer(4096, 0); - std::string filename1 = "test_file1"; - EXPECT_EQ(Store::WriteDataToStore(storePath, filename1, buffer, buffer.size()), -1); + EXPECT_EQ(Store::WriteDataToStore("", "test_file1", buffer, buffer.size()), -1); } } -- Gitee From fda3a4b576f4f66585dba49f057efa2c3265730f Mon Sep 17 00:00:00 2001 From: ma_nan Date: Mon, 11 Oct 2021 19:34:37 +0800 Subject: [PATCH 26/94] update userdata for SDCard Signed-off-by: ma_nan --- services/include/updater/updater_const.h | 3 - .../package/pkg_algorithm/pkg_algorithm.cpp | 2 +- services/package/pkg_manager/pkg_stream.cpp | 12 ++-- services/ui/updater_ui.cpp | 5 +- services/updater.cpp | 7 -- services/updater_binary/update_processor.cpp | 11 ++-- services/updater_main.cpp | 66 ++++++++++++++++--- 7 files changed, 73 insertions(+), 33 deletions(-) diff --git a/services/include/updater/updater_const.h b/services/include/updater/updater_const.h index d6b862d4..7dad0359 100644 --- a/services/include/updater/updater_const.h +++ b/services/include/updater/updater_const.h @@ -22,10 +22,7 @@ const std::string COMMAND_FILE = "/data/updater/command"; const std::string TMP_LOG = "/tmp/updater.log"; const std::string TMP_STAGE_LOG = "/tmp/updater_stage.log"; const std::string TMP_ERROR_CODE_PATH = "/tmp/error_code.log"; -const std::string ERROR_CODE_PATH = "/data/updater/log/error_code.log"; const std::string UPDATER_LOG_DIR = "/data/updater/log"; -const std::string UPDATER_LOG = "/data/updater/log/updater_log"; -const std::string UPDATER_STAGE_LOG = "/data/updater/log/updater_stage_log"; const std::string UPDATER_PATH = "/data/updater"; const std::string MISC_FILE = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/misc"; const std::string UPDATER_BINARY = "updater_binary"; diff --git a/services/package/pkg_algorithm/pkg_algorithm.cpp b/services/package/pkg_algorithm/pkg_algorithm.cpp index 61163e73..c65548ca 100644 --- a/services/package/pkg_algorithm/pkg_algorithm.cpp +++ b/services/package/pkg_algorithm/pkg_algorithm.cpp @@ -110,7 +110,7 @@ int32_t PkgAlgorithm::Unpack(const PkgStreamPtr inStream, const PkgStreamPtr out ret = FinalDigest(algorithm, context, true); PKG_CHECK(ret == 0, return ret, "Check digest fail"); - PKG_CHECK(destOffset - context.destOffset == context.packedSize, return ret, + PKG_CHECK(destOffset - context.destOffset == context.packedSize, return PKG_INVALID_STREAM, "original size error %zu %zu", destOffset, context.packedSize); context.unpackedSize = srcOffset - context.srcOffset; return ret; diff --git a/services/package/pkg_manager/pkg_stream.cpp b/services/package/pkg_manager/pkg_stream.cpp index ab2cda41..c37bab58 100644 --- a/services/package/pkg_manager/pkg_stream.cpp +++ b/services/package/pkg_manager/pkg_stream.cpp @@ -84,7 +84,12 @@ size_t FileStream::GetFileLength() PKG_CHECK(stream_ != nullptr, return 0, "Invalid stream"); if (fileLength_ == 0) { PKG_CHECK(Seek(0, SEEK_END) == 0, return -1, "Invalid stream"); - fileLength_ = ftell(stream_); + off_t pos = ftello(stream_); + if (pos < 0) { + PKG_LOGE("Failed to get file length, err = %d", errno); + return 0; + } + fileLength_ = static_cast(pos); fseek(stream_, 0, SEEK_SET); } return fileLength_; @@ -102,11 +107,6 @@ int32_t FileStream::Flush(size_t size) if (fileLength_ == 0) { fileLength_ = size; } - fseek(stream_, 0, SEEK_END); - fileLength_ = ftell(stream_); - if (size != fileLength_) { - PKG_LOGE("Flush size %zu local size:%zu", size, fileLength_); - } PKG_CHECK(fflush(stream_) == 0, return PKG_INVALID_STREAM, "Invalid stream"); return PKG_SUCCESS; } diff --git a/services/ui/updater_ui.cpp b/services/ui/updater_ui.cpp index a6902937..15957511 100644 --- a/services/ui/updater_ui.cpp +++ b/services/ui/updater_ui.cpp @@ -33,7 +33,6 @@ constexpr int LABEL_HEIGHT = 13; constexpr int MAX_IMGS = 62; constexpr int DIALIG_COLOR_A = 0xAA; constexpr int DIALOG_COLOR = 0x00; -constexpr int DISPLAY_TIME = 1000 * 1000; int g_updateFlag = 0; int g_textLabelNum = 0; @@ -169,8 +168,6 @@ void OnKeyEvent(int viewId) ShowDialog(); } else if (viewId == g_textLabel3->GetViewId() && g_textLabel3->IsVisiable()) { HideDialog(); - g_logLabel->SetText("Don't remove SD Card!"); - usleep(DISPLAY_TIME); UpdaterStatus status = UpdaterFromSdcard(); if (status != UPDATE_SUCCESS) { ShowUpdateFrame(false); @@ -521,4 +518,4 @@ void DeleteView() g_sfDev = nullptr; } } -} // namespace updater \ No newline at end of file +} // namespace updater diff --git a/services/updater.cpp b/services/updater.cpp index f5e66db3..44531918 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -132,11 +132,6 @@ static UpdaterStatus IsSpaceCapacitySufficient(const std::string &packagePath) struct statvfs64 updaterVfs; if (access("/sdcard/updater", 0) == 0) { - struct statvfs64 dataVfs {}; - UPDATER_ERROR_CHECK(statvfs64("/data", &dataVfs) >= 0, "Statvfs read /data error!", return UPDATE_ERROR); - UPDATER_ERROR_CHECK(dataVfs.f_bfree * dataVfs.f_bsize > MAX_LOG_SPACE, "/data free space is not enough", - return UPDATE_ERROR); - UPDATER_ERROR_CHECK(statvfs64("/sdcard", &updaterVfs) >= 0, "Statvfs read /sdcard error!", return UPDATE_ERROR); auto freeSpaceSize = static_cast(updaterVfs.f_bfree); auto blockSize = static_cast(updaterVfs.f_bsize); @@ -174,8 +169,6 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons g_progressBar->Hide(); ShowUpdateFrame(true); UPDATER_ERROR_CHECK(pkgManager != nullptr, "Fail to GetPackageInstance", return UPDATE_CORRUPT); - UPDATER_CHECK_ONLY_RETURN(SetupPartitions() == 0, ShowText(g_updateInfoLabel, "update failed"); - return UPDATE_ERROR); LOG(INFO) << "Verify package..."; g_updateInfoLabel->SetText("Verify package..."); diff --git a/services/updater_binary/update_processor.cpp b/services/updater_binary/update_processor.cpp index 234b5936..270c8c4f 100644 --- a/services/updater_binary/update_processor.cpp +++ b/services/updater_binary/update_processor.cpp @@ -117,7 +117,10 @@ int32_t UScriptInstructionRawImageWrite::Execute(uscript::UScriptEnv &env, uscri { std::string partitionName; int32_t ret = context.GetParam(0, partitionName); - UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS, "Error to get param", return ret); + UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS, "Error to get partitionName", return ret); + std::string imageFilename; + ret = context.GetParam(1, imageFilename); + UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS, "Error to get imageFilename", return ret); if (env.IsRetry()) { LOG(DEBUG) << "Retry updater, check if current partition updated already during last time"; @@ -136,16 +139,16 @@ int32_t UScriptInstructionRawImageWrite::Execute(uscript::UScriptEnv &env, uscri // Extract partition information hpackage::PkgManager::StreamPtr outStream = nullptr; - const FileInfo *info = env.GetPkgManager()->GetFileInfo(partitionName); + const FileInfo *info = env.GetPkgManager()->GetFileInfo(imageFilename); UPDATER_ERROR_CHECK(info != nullptr, "Error to get file info", DataWriter::ReleaseDataWriter(writer); return USCRIPT_ERROR_EXECUTE); totalSize_ = info->unpackedSize; ret = env.GetPkgManager()->CreatePkgStream(outStream, - partitionName, RawImageWriteProcessor, writer.get()); + imageFilename, RawImageWriteProcessor, writer.get()); UPDATER_ERROR_CHECK(outStream != nullptr, "Error to create output stream", DataWriter::ReleaseDataWriter(writer); return USCRIPT_ERROR_EXECUTE); - ret = env.GetPkgManager()->ExtractFile(partitionName, outStream); + ret = env.GetPkgManager()->ExtractFile(imageFilename, outStream); UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS, "Error to extract file", env.GetPkgManager()->ClosePkgStream(outStream); DataWriter::ReleaseDataWriter(writer); return USCRIPT_ERROR_EXECUTE); diff --git a/services/updater_main.cpp b/services/updater_main.cpp index d94b41d9..455ea22d 100644 --- a/services/updater_main.cpp +++ b/services/updater_main.cpp @@ -51,6 +51,7 @@ extern TextLabel *g_logLabel; extern TextLabel *g_logResultLabel; extern TextLabel *g_updateInfoLabel; extern int g_updateFlag; +constexpr int DISPLAY_TIME = 1000 * 1000; constexpr struct option OPTIONS[] = { { "update_package", required_argument, nullptr, 0 }, { "retry_count", required_argument, nullptr, 0 }, @@ -102,12 +103,35 @@ int FactoryReset(FactoryResetMode mode, const std::string &path) return DoFactoryReset(mode, path); } + +bool IsSDCardExist(const std::string &sdcardPath) +{ + //Record system error codes. + int save_errno = errno; + struct stat st {}; + if (stat(sdcardPath.c_str(), &st) < 0) { + return false; + } else { + errno = save_errno; + return true; + } +} + UpdaterStatus UpdaterFromSdcard() { #ifndef UPDATER_UT // sdcard fsType only support ext4/vfat + std::string sdcardStr = GetBlockDeviceByMountPoint(SDCARD_PATH); + if (!IsSDCardExist(sdcardStr)) { + if (errno == ENOENT) { + ShowText(g_logLabel, "Cannot detect SdCard!"); + } else { + ShowText(g_logLabel, "Detecting SdCard abnormally!"); + } + return UPDATE_ERROR; + } + if (MountForPath(SDCARD_PATH) != 0) { - std::string sdcardStr = GetBlockDeviceByMountPoint(SDCARD_PATH); int ret = mount(sdcardStr.c_str(), SDCARD_PATH.c_str(), "vfat", 0, NULL); UPDATER_WARING_CHECK(ret == 0, "MountForPath /sdcard failed!", return UPDATE_ERROR); } @@ -121,6 +145,8 @@ UpdaterStatus UpdaterFromSdcard() STAGE(UPDATE_STAGE_BEGIN) << "UpdaterFromSdcard"; LOG(INFO) << "UpdaterFromSdcard start, sdcard updaterPath : " << SDCARD_CARD_PKG_PATH; + g_logLabel->SetText("Don't remove SD Card!"); + usleep(DISPLAY_TIME); UpdaterStatus updateRet = DoInstallUpdaterPackage(pkgManager, SDCARD_CARD_PKG_PATH.c_str(), 0); if (updateRet != UPDATE_SUCCESS) { std::this_thread::sleep_for(std::chrono::milliseconds(UI_SHOW_DURATION)); @@ -155,7 +181,8 @@ static UpdaterStatus InstallUpdaterPackage(UpdaterParams &upParams, const std::v "ClearRecordPartitionOffset failed", return UPDATE_ERROR); SetRetryCountToMisc(upParams.retryCount + 1, args); } - + UPDATER_CHECK_ONLY_RETURN(SetupPartitions() == 0, ShowText(g_updateInfoLabel, "Setup partitions failed"); + return UPDATE_ERROR); status = DoInstallUpdaterPackage(manager, upParams.updatePackage, upParams.retryCount); if (status != UPDATE_SUCCESS) { std::this_thread::sleep_for(std::chrono::milliseconds(UI_SHOW_DURATION)); @@ -319,9 +346,32 @@ static bool ClearMisc() return true; } +void PostUpdaterForSdcard(std::string &updaterLogPath, std::string &stageLogPath, std::string &errorCodePath) +{ + if (SetupPartitions() != 0) { + ShowText(g_updateInfoLabel, "Mount data failed."); + LOG(ERROR) << "Mount for /data failed."; + std::string sdcardPath = GetBlockDeviceByMountPoint(SDCARD_PATH); + if (IsSDCardExist(sdcardPath)) { + if (MountForPath(SDCARD_PATH) != 0) { + int ret = mount(sdcardPath.c_str(), SDCARD_PATH.c_str(), "vfat", 0, NULL); + UPDATER_WARING_CHECK(ret == 0, "Mount for /sdcard failed!", return); + } + updaterLogPath = "/sdcard/updater/log/updater_log"; + stageLogPath = "/sdcard/updater/log/updater_stage_log"; + errorCodePath = "/sdcard/updater/log/error_code.log"; + } + } + return; +} + void PostUpdater() { STAGE(UPDATE_STAGE_BEGIN) << "PostUpdater"; + std::string updaterLogPath = "/data/updater/log/updater_log"; + std::string stageLogPath = "/data/updater/log/updater_stage_log"; + std::string errorCodePath = "/data/updater/log/error_code.log"; + PostUpdaterForSdcard(updaterLogPath, stageLogPath, errorCodePath); // clear update misc partition. UPDATER_ERROR_CHECK_NOT_RETURN(ClearMisc() == true, "PostUpdater clear misc failed"); if (!access(COMMAND_FILE.c_str(), 0)) { @@ -336,15 +386,15 @@ void PostUpdater() UPDATER_ERROR_CHECK_NOT_RETURN(DeleteUpdaterPath(SDCARD_CARD_PATH), "Delete sdcard path failed"); } // save logs - UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_LOG, UPDATER_LOG) == true, "Copy updater log failed!"); - UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_ERROR_CODE_PATH, ERROR_CODE_PATH) == true, + UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_LOG, updaterLogPath) == true, "Copy updater log failed!"); + UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_ERROR_CODE_PATH, errorCodePath) == true, "Copy error code log failed!"); mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - chmod(UPDATER_LOG.c_str(), mode); - chmod(UPDATER_STAGE_LOG.c_str(), mode); - chmod(ERROR_CODE_PATH.c_str(), mode); + chmod(updaterLogPath.c_str(), mode); + chmod(stageLogPath.c_str(), mode); + chmod(errorCodePath.c_str(), mode); STAGE(UPDATE_STAGE_SUCCESS) << "PostUpdater"; - UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_STAGE_LOG, UPDATER_STAGE_LOG) == true, "Copy stage log failed!"); + UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_STAGE_LOG, stageLogPath) == true, "Copy stage log failed!"); } std::vector ParseParams(int argc, char **argv) -- Gitee From 8d409cac5304724897ccc0580e4c10c2cba7aad3 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Mon, 11 Oct 2021 20:26:07 +0800 Subject: [PATCH 27/94] update userdata for SDCard Signed-off-by: ma_nan --- services/package/pkg_manager/pkg_stream.cpp | 2 +- services/updater_main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/package/pkg_manager/pkg_stream.cpp b/services/package/pkg_manager/pkg_stream.cpp index c37bab58..2974d4eb 100644 --- a/services/package/pkg_manager/pkg_stream.cpp +++ b/services/package/pkg_manager/pkg_stream.cpp @@ -88,7 +88,7 @@ size_t FileStream::GetFileLength() if (pos < 0) { PKG_LOGE("Failed to get file length, err = %d", errno); return 0; - } + } fileLength_ = static_cast(pos); fseek(stream_, 0, SEEK_SET); } diff --git a/services/updater_main.cpp b/services/updater_main.cpp index 455ea22d..f90b73e6 100644 --- a/services/updater_main.cpp +++ b/services/updater_main.cpp @@ -106,7 +106,7 @@ int FactoryReset(FactoryResetMode mode, const std::string &path) bool IsSDCardExist(const std::string &sdcardPath) { - //Record system error codes. + // Record system error codes. int save_errno = errno; struct stat st {}; if (stat(sdcardPath.c_str(), &st) < 0) { -- Gitee From f2eb484478b35d835c588954816680307134f6d7 Mon Sep 17 00:00:00 2001 From: ma_nan Date: Tue, 12 Oct 2021 12:08:06 +0800 Subject: [PATCH 28/94] normalize depend of crypto Signed-off-by: ma_nan --- interfaces/kits/packages/BUILD.gn | 2 +- services/BUILD.gn | 2 +- services/updater_binary/BUILD.gn | 2 +- test/fuzztest/DoPartitions_fuzzer/BUILD.gn | 2 +- test/fuzztest/ExtractAndExecuteScript_fuzzer/BUILD.gn | 2 +- test/fuzztest/UpdaterFactoryReset_fuzzer/BUILD.gn | 2 +- test/fuzztest/UpdaterStartUpdaterProc_fuzzer/BUILD.gn | 2 +- test/unittest/BUILD.gn | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/interfaces/kits/packages/BUILD.gn b/interfaces/kits/packages/BUILD.gn index 19933e10..aad7ffe4 100755 --- a/interfaces/kits/packages/BUILD.gn +++ b/interfaces/kits/packages/BUILD.gn @@ -29,7 +29,7 @@ ohos_static_library("libpackageExt") { "//base/update/updater/services/package:libupdaterpackage", "//third_party/bounds_checking_function:libsec_static", "//third_party/lz4:liblz4_static", - "//third_party/openssl:crypto_source", + "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", "//third_party/zlib:libz", ] diff --git a/services/BUILD.gn b/services/BUILD.gn index 964704d7..1b6c5c0c 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -88,7 +88,7 @@ ohos_executable("updater") { "//third_party/bzip2:libbz2", "//third_party/libdrm:libdrm", "//third_party/lz4:liblz4_static", - "//third_party/openssl:crypto_source", + "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", "//third_party/zlib:libz", ] diff --git a/services/updater_binary/BUILD.gn b/services/updater_binary/BUILD.gn index 7e8046c9..1a242386 100644 --- a/services/updater_binary/BUILD.gn +++ b/services/updater_binary/BUILD.gn @@ -53,7 +53,7 @@ ohos_executable("updater_binary") { "//third_party/bzip2:libbz2", "//third_party/cJSON:cjson_static", "//third_party/lz4:liblz4_static", - "//third_party/openssl:crypto_source", + "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", "//third_party/zlib:libz", ] diff --git a/test/fuzztest/DoPartitions_fuzzer/BUILD.gn b/test/fuzztest/DoPartitions_fuzzer/BUILD.gn index c48c7433..7732b731 100644 --- a/test/fuzztest/DoPartitions_fuzzer/BUILD.gn +++ b/test/fuzztest/DoPartitions_fuzzer/BUILD.gn @@ -45,7 +45,7 @@ ohos_fuzztest("DoPartitionsFuzzTest") { "//third_party/bzip2:libbz2", "//third_party/libdrm:libdrm", "//third_party/lz4:liblz4_static", - "//third_party/openssl:crypto_source", + "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", "//third_party/zlib:libz", "//utils/native/base:utils", diff --git a/test/fuzztest/ExtractAndExecuteScript_fuzzer/BUILD.gn b/test/fuzztest/ExtractAndExecuteScript_fuzzer/BUILD.gn index 0632f8e8..8f1763b0 100644 --- a/test/fuzztest/ExtractAndExecuteScript_fuzzer/BUILD.gn +++ b/test/fuzztest/ExtractAndExecuteScript_fuzzer/BUILD.gn @@ -54,7 +54,7 @@ ohos_fuzztest("ExtractAndExecuteScriptFuzzTest") { "//third_party/bzip2:libbz2", "//third_party/libdrm:libdrm", "//third_party/lz4:liblz4_static", - "//third_party/openssl:crypto_source", + "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", "//third_party/zlib:libz", "//utils/native/base:utils", diff --git a/test/fuzztest/UpdaterFactoryReset_fuzzer/BUILD.gn b/test/fuzztest/UpdaterFactoryReset_fuzzer/BUILD.gn index b644afb7..619dabc7 100644 --- a/test/fuzztest/UpdaterFactoryReset_fuzzer/BUILD.gn +++ b/test/fuzztest/UpdaterFactoryReset_fuzzer/BUILD.gn @@ -47,7 +47,7 @@ ohos_fuzztest("UpdaterFactoryResetFuzzTest") { "//third_party/bzip2:libbz2", "//third_party/libdrm:libdrm", "//third_party/lz4:liblz4_static", - "//third_party/openssl:crypto_source", + "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", "//third_party/zlib:libz", ] diff --git a/test/fuzztest/UpdaterStartUpdaterProc_fuzzer/BUILD.gn b/test/fuzztest/UpdaterStartUpdaterProc_fuzzer/BUILD.gn index c43acd69..5ef91cb5 100644 --- a/test/fuzztest/UpdaterStartUpdaterProc_fuzzer/BUILD.gn +++ b/test/fuzztest/UpdaterStartUpdaterProc_fuzzer/BUILD.gn @@ -51,7 +51,7 @@ ohos_fuzztest("UpdaterStartUpdaterProcFuzzTest") { "//third_party/libdrm:libdrm", "//third_party/libpng:libpng", "//third_party/lz4:liblz4_static", - "//third_party/openssl:crypto_source", + "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", "//third_party/zlib:libz", ] diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 0fae483e..0d5d617e 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -201,7 +201,7 @@ ohos_unittest("updater_unittest") { "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", "//third_party/lz4:liblz4_static", - "//third_party/openssl:crypto_source", + "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", "//third_party/zlib:libz", ] -- Gitee From 9cf5e305bf9c9f4aac52a151d18b53a94c6912b7 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Mon, 18 Oct 2021 15:38:42 +0800 Subject: [PATCH 29/94] updater: fix code style Signed-off-by: sun_fan --- services/fs_manager/mount.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/services/fs_manager/mount.cpp b/services/fs_manager/mount.cpp index 20f99e76..2b33668d 100644 --- a/services/fs_manager/mount.cpp +++ b/services/fs_manager/mount.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "fs_manager/mount.h" + #include #include #include -- Gitee From 1fd392d1a06a17ca333fde4f9d943e0d4aa83c59 Mon Sep 17 00:00:00 2001 From: "411148299@qq.com" <411148299@qq.com> Date: Mon, 18 Oct 2021 15:55:59 +0800 Subject: [PATCH 30/94] fix code style Signed-off-by: 411148299@qq.com <411148299@qq.com> --- interfaces/kits/misc_info/BUILD.gn | 1 + ohos.build | 6 +- services/BUILD.gn | 19 +- services/applypatch/BUILD.gn | 1 + services/applypatch/transfer_manager.cpp | 14 +- services/etc/init.cfg | 37 +- services/etc/init.usb.cfg | 15 + services/etc/init.usb.configfs.cfg | 25 + services/flashd/BUILD.gn | 80 +++ services/flashd/blockdevice.cpp | 55 ++ .../fstab.h => flashd/blockdevice.h} | 93 +-- services/flashd/daemon/daemon_updater.cpp | 207 ++++++ services/flashd/daemon/daemon_updater.h | 58 ++ .../daemon/flashd_main.cpp} | 53 +- services/flashd/flash_service.cpp | 612 ++++++++++++++++++ services/flashd/flash_service.h | 77 +++ services/flashd/flash_utils.h | 49 ++ services/flashd/host/host_updater.cpp | 260 ++++++++ services/flashd/host/host_updater.h | 62 ++ services/flashd/partition.cpp | 419 ++++++++++++ services/flashd/partition.h | 82 +++ services/fs_manager/BUILD.gn | 3 +- services/fs_manager/fstab.cpp | 216 ------- services/fs_manager/mount.cpp | 293 ++------- .../include/applypatch/partition_record.h | 2 +- .../include/applypatch/transfer_manager.h | 1 + services/include/applypatch/updater_env.h | 7 +- services/include/flashd/flashd.h | 73 +++ services/include/fs_manager/fstab_api.h | 28 - services/include/fs_manager/mount.h | 12 +- services/include/package/pkg_manager.h | 13 + services/include/updater/updater.h | 17 + services/include/updater/updater_const.h | 2 + services/main.cpp | 34 +- .../package/pkg_manager/pkg_managerImpl.cpp | 37 +- .../package/pkg_manager/pkg_manager_impl.h | 8 + services/package/pkg_manager/pkg_stream.cpp | 10 + services/package/pkg_manager/pkg_stream.h | 22 +- services/package/pkg_package/pkg_gzipfile.h | 3 +- services/package/pkg_package/pkg_lz4file.h | 3 +- services/package/pkg_package/pkg_pkgfile.cpp | 2 + services/package/pkg_package/pkg_pkgfile.h | 4 +- .../package/pkg_package/pkg_upgradefile.cpp | 1 + .../package/pkg_package/pkg_upgradefile.h | 6 +- services/package/pkg_package/pkg_zipfile.h | 3 +- services/ui/surface_dev.cpp | 2 +- services/ui/surface_dev.h | 4 +- services/ui/updater_ui.cpp | 15 + services/ui/updater_ui.h | 7 + services/updater.cpp | 127 ++-- services/updater_binary/BUILD.gn | 1 + services/updater_binary/main.cpp | 2 + services/updater_binary/update_partitions.cpp | 2 +- services/updater_binary/update_processor.cpp | 56 +- services/updater_main.cpp | 152 +---- services/updater_main.h | 4 - services/updater_utils.cpp | 290 +++++++++ .../ReadFstabFromFile_fuzzer.cpp | 8 +- test/unittest/BUILD.gn | 26 +- .../flashd_test/flash_host_unittest.cpp | 104 +++ .../flashd_test/flash_service_unittest.cpp | 411 ++++++++++++ .../unittest/mount_test/fstabapi_unittest.cpp | 83 +-- test/unittest/mount_test/mount_unittest.cpp | 26 +- .../unittest/package/pkg_manager_unittest.cpp | 7 +- .../unittest/package/pkg_package_unittest.cpp | 16 +- .../updater_main_unittest.cpp | 7 +- .../updater_test/updater_unittest.cpp | 7 + utils/BUILD.gn | 2 + utils/include/utils.h | 4 +- utils/updater_reboot.cpp | 6 +- utils/utils.cpp | 116 +--- 71 files changed, 3495 insertions(+), 1015 deletions(-) create mode 100755 services/etc/init.usb.cfg create mode 100755 services/etc/init.usb.configfs.cfg create mode 100755 services/flashd/BUILD.gn create mode 100755 services/flashd/blockdevice.cpp rename services/{include/fs_manager/fstab.h => flashd/blockdevice.h} (40%) mode change 100644 => 100755 create mode 100755 services/flashd/daemon/daemon_updater.cpp create mode 100755 services/flashd/daemon/daemon_updater.h rename services/{include/sparse_image/sparse_image_api.h => flashd/daemon/flashd_main.cpp} (30%) mode change 100644 => 100755 create mode 100755 services/flashd/flash_service.cpp create mode 100755 services/flashd/flash_service.h create mode 100755 services/flashd/flash_utils.h create mode 100755 services/flashd/host/host_updater.cpp create mode 100755 services/flashd/host/host_updater.h create mode 100755 services/flashd/partition.cpp create mode 100755 services/flashd/partition.h delete mode 100644 services/fs_manager/fstab.cpp create mode 100755 services/include/flashd/flashd.h delete mode 100644 services/include/fs_manager/fstab_api.h create mode 100755 services/updater_utils.cpp create mode 100755 test/unittest/flashd_test/flash_host_unittest.cpp create mode 100755 test/unittest/flashd_test/flash_service_unittest.cpp diff --git a/interfaces/kits/misc_info/BUILD.gn b/interfaces/kits/misc_info/BUILD.gn index 51b347ca..7bcc7112 100755 --- a/interfaces/kits/misc_info/BUILD.gn +++ b/interfaces/kits/misc_info/BUILD.gn @@ -21,6 +21,7 @@ ohos_static_library("libmiscinfo") { "//base/update/updater/services/include", "//base/update/updater/utils/include", "//third_party/bounds_checking_function/include", + "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ diff --git a/ohos.build b/ohos.build index 9ef224ed..341a12ee 100644 --- a/ohos.build +++ b/ohos.build @@ -27,10 +27,12 @@ "//base/update/updateservice/interfaces/innerkits/engine:updateservicekits", "//base/update/updater/services/ui:libui", "//third_party/libdrm:libdrm", - "//third_party/e2fsprogs:e2fsprogs" + "//third_party/e2fsprogs:e2fsprogs", + "//base/update/updater/services/flashd:updater_flashd" ], "test_list": [ - "//base/update/updater:unittest" + "//base/update/updater:unittest", + "//base/update/updateservice:unittest" ] } } diff --git a/services/BUILD.gn b/services/BUILD.gn index 1b6c5c0c..945f511d 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -21,6 +21,18 @@ ohos_prebuilt_etc("updater_init.cfg") { part_name = "updater" } +ohos_prebuilt_etc("updater_usb_init.cfg") { + source = "//base/update/updater/services/etc/init.usb.cfg" + install_images = [ "updater" ] + part_name = "updater" +} + +ohos_prebuilt_etc("updater_init_usb_configfs.cfg") { + source = "//base/update/updater/services/etc/init.usb.configfs.cfg" + install_images = [ "updater" ] + part_name = "updater" +} + ohos_prebuilt_etc("signing_cert.crt") { source = "//device/hisilicon/hi3516dv300/build/updater_config/signing_cert.crt" @@ -40,6 +52,8 @@ group("updater_etc") { ":fstab.updater", ":signing_cert.crt", ":updater_init.cfg", + ":updater_init_usb_configfs.cfg", + ":updater_usb_init.cfg", ] } @@ -49,12 +63,13 @@ ohos_executable("updater") { "main.cpp", "updater.cpp", "updater_main.cpp", + "updater_utils.cpp", ] include_dirs = [ "include", "$SUBSYSTEM_DIR/utils/include", - "$SUBSYSTEM_DIR/interfaces/kits/include/", + "$SUBSYSTEM_DIR/interfaces/kits/include", "//third_party/bounds_checking_function/include", "//base/update/updater/services/include/package", "//base/update/updater/services/package/pkg_manager", @@ -72,6 +87,7 @@ ohos_executable("updater") { "//base/update/updater/services", "//base/update/updater/services/ui", "//base/update/updater/services/include", + "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ @@ -79,6 +95,7 @@ ohos_executable("updater") { "//base/update/updater/interfaces/kits/packages:libpackageExt", "//base/update/updater/services/applypatch:libapplypatch", "//base/update/updater/services/diffpatch/patch:libpatch", + "//base/update/updater/services/flashd:libflashd", "//base/update/updater/services/fs_manager:libfsmanager", "//base/update/updater/services/log:libupdaterlog", "//base/update/updater/services/package:libupdaterpackage", diff --git a/services/applypatch/BUILD.gn b/services/applypatch/BUILD.gn index 8d8d8725..43765bfd 100644 --- a/services/applypatch/BUILD.gn +++ b/services/applypatch/BUILD.gn @@ -39,6 +39,7 @@ ohos_static_library("libapplypatch") { "//base/update/updater/services/include/package", "//base/update/updater/services/include/log", "//third_party/bounds_checking_function/include", + "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ diff --git a/services/applypatch/transfer_manager.cpp b/services/applypatch/transfer_manager.cpp index 00d88b48..6ba2e13d 100644 --- a/services/applypatch/transfer_manager.cpp +++ b/services/applypatch/transfer_manager.cpp @@ -91,11 +91,7 @@ bool TransferManager::CommandsParser(int fd, const std::vector &con if (initBlock == 0) { initBlock = globalParams->written; } - bool typeResult = cmd->GetCommandType() == CommandType::NEW || - cmd->GetCommandType() == CommandType::IMGDIFF || - cmd->GetCommandType() == CommandType::BSDIFF || - cmd->GetCommandType() == CommandType::ZERO; - if (totalSize != 0 && globalParams->env != nullptr && typeResult) { + if (totalSize != 0 && globalParams->env != nullptr && NeedSetProgress(cmd->GetCommandType())) { globalParams->env->PostMessage("set_progress", std::to_string((float)(globalParams->written - initBlock) / totalSize)); } @@ -140,6 +136,14 @@ std::string TransferManager::ReloadForRetry() const return cmd; } +bool TransferManager::NeedSetProgress(const CommandType &type) +{ + return type == CommandType::NEW || + type == CommandType::IMGDIFF || + type == CommandType::BSDIFF || + type == CommandType::ZERO; +} + bool TransferManager::CheckResult(const CommandResult result, const std::string &cmd, const CommandType &type) { switch (result) { diff --git a/services/etc/init.cfg b/services/etc/init.cfg index 5615a7d6..cefe21d4 100755 --- a/services/etc/init.cfg +++ b/services/etc/init.cfg @@ -13,18 +13,42 @@ "cmds" : [ "mkdir /system", "mkdir /vendor", - "mkdir /odm", - "mkdir /hos", "mkdir /tmp", "mount tmpfs tmpfs /tmp", "chown 0 2000 /tmp", - "chmod 0755 /tmp" + "chmod 0755 /tmp", + "mkdir /dev/usb-ffs 0770 shell shell", + "mkdir /dev/usb-ffs/hdc 0770 shell shell", + "mkdir /dev/usb-ffs/hdc 0770 shell shell", + "mkdir /config 0770 shell shell", + "mount configfs none /config", + "mkdir /config/usb_gadget/g1 0770 shell shell", + "write /config/usb_gadget/g1/idVendor 0x12D1", + "write /config/usb_gadget/g1/idProduct 0x5000", + "write /config/usb_gadget/g1/os_desc/use 1", + "write /config/usb_gadget/g1/bcdDevice 0x0223", + "write /config/usb_gadget/g1/bcdUSB 0x0200", + "mkdir /config/usb_gadget/g1/strings/0x409 0770", + "copy /sys/block/mmcblk0/device/cid /config/usb_gadget/g1/strings/0x409/serialnumber", + "write /config/usb_gadget/g1/strings/0x409/manufacturer HISILICON", + "write /config/usb_gadget/g1/strings/0x409/product \"HDC Device\"", + "mkdir /config/usb_gadget/g1/functions/ffs.hdc", + "mkdir /config/usb_gadget/g1/configs/b.1 0770 shell shell", + "mkdir /config/usb_gadget/g1/configs/b.1/strings/0x409 0770 shell shell", + "write /config/usb_gadget/g1/os_desc/b_vendor_code 0x1", + "write /config/usb_gadget/g1/os_desc/qw_sign MSFT100", + "write /config/usb_gadget/g1/configs/b.1/MaxPower 500", + "symlink /config/usb_gadget/g1/configs/b.1 /config/usb_gadget/g1/os_desc/b.1", + "mount functionfs hdc /dev/usb-ffs/hdc uid=2000,gid=2000", + "setparam sys.usb.controller 100e0000.hidwc3_0", + "setparam sys.usb.config hdc", + "setparam sys.usb.configfs 1" ] }, { "name" : "post-init", "cmds" : [ - "start updater", - "start shell" + "start shell", + "start updater" ] } ], @@ -35,8 +59,7 @@ "gid" : 2000, "once" : 0, "importance" : 0, - "console" : 1, - "caps" : [4294967295] + "console" : 1 }, { "name" : "updater", "path" : ["/bin/updater"], diff --git a/services/etc/init.usb.cfg b/services/etc/init.usb.cfg new file mode 100755 index 00000000..1a307221 --- /dev/null +++ b/services/etc/init.usb.cfg @@ -0,0 +1,15 @@ +{ + "jobs" : [{ + "name" : "boot", + "cmds" : [ + "setparam sys.usb.configfs 0" + ] + }, { + "name" : "boot && param:persist.sys.usb.config=*", + "condition" : "boot && persist.sys.usb.config=*", + "cmds" : [ + "setparam sys.usb.config ${persist.sys.usb.config}" + ] + } + ] +} diff --git a/services/etc/init.usb.configfs.cfg b/services/etc/init.usb.configfs.cfg new file mode 100755 index 00000000..4474b098 --- /dev/null +++ b/services/etc/init.usb.configfs.cfg @@ -0,0 +1,25 @@ +{ + "jobs" : [{ + "name" : "param:sys.usb.config=none && param:sys.usb.configfs=1", + "condition" : "sys.usb.config=none && sys.usb.configfs=1", + "cmds" : [ + "write /config/usb_gadget/g1/UDC none", + "setparam sys.usb.ffs.ready 0", + "write /config/usb_gadget/g1/bDeviceClass 0", + "write /config/usb_gadget/g1/bDeviceSubClass 0", + "write /config/usb_gadget/g1/bDeviceProtocol 0", + "rm /config/usb_gadget/g1/configs/b.1/f1", + "setparam sys.usb.state ${sys.usb.config}" + ] + }, { + "name" : "param:sys.usb.ffs.ready=1 && param:sys.usb.config=hdc && param:sys.usb.configfs=1", + "condition" : "sys.usb.ffs.ready=1 && sys.usb.config=hdc && sys.usb.configfs=1", + "cmds" : [ + "write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration hdc", + "symlink /config/usb_gadget/g1/functions/ffs.hdc /config/usb_gadget/g1/configs/b.1/f1", + "write /config/usb_gadget/g1/UDC ${sys.usb.controller}", + "setparam sys.usb.state ${sys.usb.config}" + ] + } + ] +} diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn new file mode 100755 index 00000000..d484a64c --- /dev/null +++ b/services/flashd/BUILD.gn @@ -0,0 +1,80 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_static_library("libflashd") { + sources = [ + "//base/update/updater/services/flashd/blockdevice.cpp", + "//base/update/updater/services/flashd/daemon/daemon_updater.cpp", + "//base/update/updater/services/flashd/daemon/flashd_main.cpp", + "//base/update/updater/services/flashd/flash_service.cpp", + "//base/update/updater/services/flashd/partition.cpp", + "//base/update/updater/services/updater_binary/update_image_block.cpp", + "//base/update/updater/services/updater_binary/update_partitions.cpp", + "//base/update/updater/services/updater_binary/update_processor.cpp", + ] + + defines = [ + "HDC_DEBUG", + "HDC_SUPPORT_FLASHD", + "HARMONY_PROJECT", + ] + + deps = [ + "//base/update/updater/interfaces/kits/misc_info:libmiscinfo", + "//base/update/updater/services/applypatch:libapplypatch", + "//base/update/updater/services/diffpatch/patch:libpatch", + "//base/update/updater/services/fs_manager:libfsmanager", + "//base/update/updater/services/log:libupdaterlog", + "//base/update/updater/services/package:libupdaterpackage", + "//base/update/updater/services/script:libupdaterscript", + "//base/update/updater/utils:libutils", + "//developtools/hdc_standard:hdc_deamon_flashd", + "//third_party/bzip2:libbz2", + "//third_party/cJSON:cjson_static", + "//third_party/libuv:uv_static", + "//third_party/lz4:liblz4_static", + "//third_party/openssl:libcrypto_static", + "//third_party/openssl:ssl_source", + "//third_party/zlib:libz", + "//utils/native/base:utils", + ] + + include_dirs = [ + "//developtools/hdc_standard/src/daemon", + "//developtools/hdc_standard/src/common", + "//base/update/updater/services", + "//base/update/updater/services/flashd", + "//base/update/updater/services/flashd/daemon", + "//base/update/updater/interfaces/kits/include", + "//base/update/updater/services/include/package", + "//base/update/updater/services/include/script", + "//base/update/updater/services/include/log", + "//base/update/updater/services/include", + "//base/update/updater/utils/include", + "//third_party/bounds_checking_function/include", + "//third_party/cJSON", + "//third_party/openssl/include", + "//utils/native/base/include", + "//third_party/lz4/lib", + "//third_party/libuv", + "//base/startup/init_lite/interfaces/innerkits/include", + ] + + part_name = "updater" +} + +group("updater_flashd") { + deps = [ ":libflashd" ] +} diff --git a/services/flashd/blockdevice.cpp b/services/flashd/blockdevice.cpp new file mode 100755 index 00000000..02d2d239 --- /dev/null +++ b/services/flashd/blockdevice.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "blockdevice.h" +#include +#include +#include +#include +#include +#include +#include "flash_service.h" + +namespace flashd { +int BlockDevice::Load() +{ + struct stat devStat {}; + int ret = stat(devPath_.c_str(), &devStat); + FLASHING_CHECK(ret != -1, return -1, "Failed to state %s", devPath_.c_str()); + + const std::string devName = GetDeviceName(); + std::string size = ReadDeviceSysInfo("size"); + FLASHING_CHECK(!size.empty(), return 0, "Failed to read dev size"); + devSize_ = atol(size.c_str()); + sectorSize_ = SECTOR_SIZE_DEFAULT; + physSectorSize_ = SECTOR_SIZE_DEFAULT; + return 0; +} + +const std::string BlockDevice::GetDeviceName() +{ + std::string::size_type pos = devPath_.find_last_of('/') + 1; + return devPath_.substr(pos, devPath_.size() - pos); +} + +std::string BlockDevice::ReadDeviceSysInfo(const std::string &type) +{ + std::vector buffer(DEVICE_PATH_SIZE, 0); + int ret = snprintf_s(buffer.data(), DEVICE_PATH_SIZE, DEVICE_PATH_SIZE - 1, + "/sys/block/%s/%s", GetDeviceName().c_str(), type.c_str()); + FLASHING_CHECK(ret != -1, return "", "Failed to snprintf_s %s", devPath_.c_str()); + std::vector table; + return FlashService::ReadSysInfo(buffer.data(), type, table); +} +} // namespace flashd \ No newline at end of file diff --git a/services/include/fs_manager/fstab.h b/services/flashd/blockdevice.h old mode 100644 new mode 100755 similarity index 40% rename from services/include/fs_manager/fstab.h rename to services/flashd/blockdevice.h index 4cf3b750..3533a586 --- a/services/include/fs_manager/fstab.h +++ b/services/flashd/blockdevice.h @@ -1,42 +1,51 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef __UPDATER_FS_MANAGER_FSTAB_H -#define __UPDATER_FS_MANAGER_FSTAB_H -#include -#include -#include - -namespace updater { -/* Fs manager flags definition */ -#define FS_MANAGER_CHECK 0x00000001 -#define FS_MANAGER_WAIT 0x00000002 - -#define VALID_FS_MANAGER_FLAGS (FS_MANAGER_CHECK | FS_MANAGER_WAIT) -#define FS_MANAGER_FLAGS_ENABLED(item, flag) ((item.fsManagerFlags & FS_MANAGER_##flag) != 0) - -#define FM_MANAGER_CHECK_ENABLED(item, flag) FS_MANAGER_FLAGS_ENABLED(item, check) -#define FM_MANAGER_WAIT_ENABLED(item, flag) FS_MANAGER_FLAGS_ENABLED(item, wait) - -struct FstabItem { - std::string deviceName; // Block device name - std::string mountPoint; // Mount point - std::string fsType; // File system type - std::string mountOptions; // File system mount options. readonly, rw, remount etc. - unsigned int fsManagerFlags; // flags defined by fs manager. -}; - -using Fstab = std::vector; -} // updater -#endif // __UPDATER_FS_MANAGER_H +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef FLASHING_BLOCKDEVICE_H +#define FLASHING_BLOCKDEVICE_H +#include +#include +#include "flash_utils.h" + +namespace flashd { +enum class DeviceType { + DEVICE_UNKNOWN = 0, + DEVICE_SCSI = 1, + DEVICE_EMMC = 2, +}; + +class BlockDevice { +public: + BlockDevice(DeviceType type, const std::string &devPath) : devPath_(devPath), type_(type) {} + ~BlockDevice() {}; + + int Load(); + const std::string GetDeviceName(); + DeviceType GetDeviceType() + { + return type_; + } +private: + std::string ReadDeviceSysInfo(const std::string &type); + + std::string devPath_; + size_t devSize_ = 0; + size_t sectorSize_ = 0; // logical sector size + size_t physSectorSize_ = 0; // physical sector size + DeviceType type_ = DeviceType::DEVICE_UNKNOWN; +}; +using BlockDevicePtr = BlockDevice *; +} +#endif // FLASHING_BLOCKDEVICE_H \ No newline at end of file diff --git a/services/flashd/daemon/daemon_updater.cpp b/services/flashd/daemon/daemon_updater.cpp new file mode 100755 index 00000000..37dae05c --- /dev/null +++ b/services/flashd/daemon/daemon_updater.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "daemon_updater.h" +#include "daemon_common.h" +#include "flashd/flashd.h" +#include "flash_utils.h" + +namespace Hdc { +DaemonUpdater::DaemonUpdater(HTaskInfo hTaskInfo) : HdcTransferBase(hTaskInfo) +{ + commandBegin = CMD_UPDATER_BEGIN; + commandData = CMD_UPDATER_DATA; +} + +DaemonUpdater::~DaemonUpdater() +{ + WRITE_LOG(LOG_DEBUG, "~DaemonUpdater refCount %d", refCount); +} + +bool DaemonUpdater::ReadyForRelease() +{ + if (!HdcTaskBase::ReadyForRelease()) { + return false; + } + return true; +} + +bool DaemonUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ +#ifndef UPDATER_UT + if (!HdcTransferBase::CommandDispatch(command, payload, payloadSize)) { + return false; + } +#endif + if (flashHandle_ == nullptr) { + int ret = flashd::CreateFlashInstance(&flashHandle_, errorMsg_, + [&](uint32_t type, size_t dataLen, const void *context) { + SendProgress(dataLen); + }); + if (ret != 0) { + return false; + } + } + switch (command) { + case CMD_UPDATER_DATA: { + string serialStrring((char *)payload, payloadPrefixReserve); + TransferPayload pld; + SerialStruct::ParseFromString(pld, serialStrring); + SendProgress(pld.uncompressSize); + break; + } + case CMD_UPDATER_CHECK: { + ProcessUpdateCheck(payload, payloadSize); + break; + } + case CMD_UPDATER_ERASE: { + std::string param(reinterpret_cast(payload), payloadSize); + RunUpdateShell(flashd::UPDATEMOD_ERASE, param, ""); + TaskFinish(); + break; + } + case CMD_UPDATER_FORMAT: { + std::string param(reinterpret_cast(payload), payloadSize); + RunUpdateShell(flashd::UPDATEMOD_FORMAT, param, ""); + TaskFinish(); + break; + } + default: + WRITE_LOG(LOG_FATAL, "CommandDispatch command %d", command); + return false; + } + return true; +}; + +void DaemonUpdater::ProcessUpdateCheck(const uint8_t *payload, const int payloadSize) +{ + uint64_t realSize = 0; + int ret = memcpy_s(&realSize, sizeof(realSize), payload, sizeof(realSize)); + if (ret != 0) { + return; + } + string bufString((char *)payload + sizeof(realSize), payloadSize - sizeof(realSize)); + SerialStruct::ParseFromString(ctxNow.transferConfig, bufString); + ctxNow.master = false; + ctxNow.fsOpenReq.data = &ctxNow; + ctxNow.transferBegin = Base::GetRuntimeMSec(); + ctxNow.fileSize = ctxNow.transferConfig.fileSize; + percentage_ = -1; + + WRITE_LOG(LOG_DEBUG, "ProcessUpdateCheck local function %s size %llu realSize %llu", + ctxNow.transferConfig.functionName.c_str(), ctxNow.fileSize, realSize); + uint8_t type = flashd::UPDATEMOD_FLASH; + if (ctxNow.transferConfig.functionName == CMDSTR_UPDATE_SYSTEM) { + type = flashd::UPDATEMOD_UPDATE; + totalSize_ = static_cast(ctxNow.fileSize); + if (!MatchPackageExtendName(ctxNow.transferConfig.optionalName, ".bin")) { + totalSize_ += static_cast(realSize); // for decode from zip + } + totalSize_ += static_cast(realSize); // for verify + totalSize_ += static_cast(realSize); // for read to partition + totalSize_ += static_cast(realSize); // for write partition + } else if (ctxNow.transferConfig.functionName == CMDSTR_FLASH_PARTITION) { + totalSize_ = static_cast(ctxNow.fileSize); + type = flashd::UPDATEMOD_FLASH; + } else { + WRITE_LOG(LOG_FATAL, "ProcessUpdateCheck local function %s size %lu realSize %lu", + ctxNow.transferConfig.functionName.c_str(), ctxNow.fileSize, realSize); + return; + } + ctxNow.localPath = ctxNow.transferConfig.optionalName; + ret = flashd::DoUpdaterPrepare(flashHandle_, type, ctxNow.transferConfig.options, ctxNow.localPath); + if (ret == 0) { + refCount++; + WRITE_LOG(LOG_DEBUG, "ProcessUpdateCheck localPath %s", ctxNow.localPath.c_str()); + uv_fs_open(loopTask, &ctxNow.fsOpenReq, ctxNow.localPath.c_str(), + UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IRUSR, OnFileOpen); + } else { + AsyncUpdateFinish(type, ret, errorMsg_); + } +} + +void DaemonUpdater::RunUpdateShell(uint8_t type, const std::string &options, const std::string &package) +{ + int ret = flashd::DoUpdaterFlash(flashHandle_, type, options, package); + if (ret != 0) { + WRITE_LOG(LOG_FATAL, errorMsg_.c_str()); + } + AsyncUpdateFinish(type, ret, errorMsg_); +} + +void DaemonUpdater::SendProgress(size_t dataLen) +{ + currSize_ += dataLen; + int32_t percentage = (int32_t)(currSize_ * (flashd::PERCENT_FINISH - 1) / totalSize_); + if (percentage >= flashd::PERCENT_FINISH) { + WRITE_LOG(LOG_DEBUG, "SendProgress %lf percentage %d", currSize_, percentage); + return; + } + if (percentage_ < percentage) { + percentage_ = percentage; + WRITE_LOG(LOG_DEBUG, "SendProgress %lf percentage_ %d", currSize_, percentage_); + FLASHING_LOGI("SendProgress %lf percentage_ %d", currSize_, percentage_); + SendToAnother(CMD_UPDATER_PROGRESS, (uint8_t *)&percentage, sizeof(uint32_t)); + } +} + +void DaemonUpdater::WhenTransferFinish(CtxFile *context) +{ + uint64_t nMSec = Base::GetRuntimeMSec() - context->transferBegin; + double fRate = static_cast(context->indexIO) / nMSec; // / /1000 * 1000 = 0 + WRITE_LOG(LOG_DEBUG, "File for %s transfer finish Size:%lld time:%lldms rate:%.2lfkB/s", + ctxNow.transferConfig.functionName.c_str(), context->indexIO, nMSec, fRate); + + int ret = 0; + uint8_t type = flashd::UPDATEMOD_UPDATE; + if (ctxNow.transferConfig.functionName == CMDSTR_UPDATE_SYSTEM) { + type = flashd::UPDATEMOD_UPDATE; + ret = flashd::DoUpdaterFlash(flashHandle_, type, ctxNow.transferConfig.options, ctxNow.localPath); + } else if (ctxNow.transferConfig.functionName == CMDSTR_FLASH_PARTITION) { + type = flashd::UPDATEMOD_FLASH; + } + AsyncUpdateFinish(type, ret, errorMsg_); + ret = flashd::DoUpdaterFinish(flashHandle_, type, ctxNow.localPath); + if (ret != 0) { + WRITE_LOG(LOG_FATAL, errorMsg_.c_str()); + } + TaskFinish(); +} + +void DaemonUpdater::AsyncUpdateFinish(uint8_t type, int32_t ret, const string &result) +{ + WRITE_LOG(LOG_DEBUG, "AsyncUpdateFinish ret %d result %s", ret, result.c_str()); + uint32_t percentage = (ret != 0) ? flashd::PERCENT_CLEAR : flashd::PERCENT_FINISH; + SendToAnother(CMD_UPDATER_PROGRESS, (uint8_t *)&percentage, sizeof(uint32_t)); + + string echo = result; + echo = Base::ReplaceAll(echo, "\n", " "); + vector vecBuf; + vecBuf.push_back(type); + if (ret != 0) { + vecBuf.push_back(MSG_FAIL); + } else { + vecBuf.push_back(MSG_OK); + } + vecBuf.insert(vecBuf.end(), (uint8_t *)echo.c_str(), (uint8_t *)echo.c_str() + echo.size()); + SendToAnother(CMD_UPDATER_FINISH, vecBuf.data(), vecBuf.size()); +} + +#ifdef UPDATER_UT +void DaemonUpdater::DoTransferFinish() +{ + WhenTransferFinish(&ctxNow); +} +#endif +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/daemon/daemon_updater.h b/services/flashd/daemon/daemon_updater.h new file mode 100755 index 00000000..a7e35b67 --- /dev/null +++ b/services/flashd/daemon/daemon_updater.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DAEMON_UPDATER_H +#define HDC_DAEMON_UPDATER_H +#include + +#include "securec.h" +#include "transfer.h" + +namespace Hdc { +class DaemonUpdater : public HdcTransferBase { +public: + explicit DaemonUpdater(HTaskInfo hTaskInfo); + virtual ~DaemonUpdater(); + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) override; + bool ReadyForRelease(); +#ifdef UPDATER_UT + void DoTransferFinish(); +#endif +private: + virtual void WhenTransferFinish(CtxFile *context) override; + void ProcessUpdateCheck(const uint8_t *payload, const int payloadSize); + void RunUpdateShell(uint8_t type, const std::string &options, const std::string &package); + void AsyncUpdateFinish(uint8_t type, int32_t ret, const string &result); + void SendProgress(size_t dataLen); +#ifdef UPDATER_UT + bool SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size) + { + WRITE_LOG(LOG_DEBUG, "SendToAnother %d size %d", command, size); + return true; + } + void TaskFinish() + { + WRITE_LOG(LOG_DEBUG, "TaskFinish "); + return; + } +#endif +private: + double currSize_ = 0; + double totalSize_ = 0; + int32_t percentage_ = 0; + void* flashHandle_ = nullptr; + std::string errorMsg_ {}; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/include/sparse_image/sparse_image_api.h b/services/flashd/daemon/flashd_main.cpp old mode 100644 new mode 100755 similarity index 30% rename from services/include/sparse_image/sparse_image_api.h rename to services/flashd/daemon/flashd_main.cpp index 210541e4..5d73fd8f --- a/services/include/sparse_image/sparse_image_api.h +++ b/services/flashd/daemon/flashd_main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (C) 2021 Huawei Device Co., Ltd. * 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 @@ -12,15 +12,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "daemon_common.h" +#include "flashd/flashd.h" +#include "updater/updater.h" -#ifndef UPDATER_SPARSE_IMAGE_API_H -#define UPDATER_SPARSE_IMAGE_API_H -namespace updater { -// SparseImage structure is an internal structure of libsparseimage -// Just declare it here. -struct SparseImage; -struct SparseImage *CreateSparseImageFromBuffer(char *buff); -void DeallocateSparseImage(struct SparseImage *si); -int SparseImageRestore(int fd, struct SparseImage *si); -} // namespace updater -#endif // UPDATER_SPARSE_IMAGE_API_H +using namespace Hdc; +namespace flashd { +int flashd_main(int argc, char **argv) +{ + Base::SetLogLevel(LOG_LAST); // debug log print + std::vector args = updater::ParseParams(argc, argv); + bool enableUsb = false; + bool enableTcp = false; + for (std::string arg : args) { + if (arg.find("-l") != std::string::npos) { + int logLevel = atoi(arg.c_str() + strlen("-l")); + if (logLevel < 0 || logLevel > LOG_LAST) { + WRITE_LOG(LOG_DEBUG, "Loglevel error!\n"); + return -1; + } + Base::SetLogLevel(logLevel); + } else if (arg.find("-t") != std::string::npos) { + enableTcp = true; + } else if (arg.find("-u") != std::string::npos) { + enableUsb = true; + } + } + + if (!enableTcp && !enableUsb) { + Base::PrintMessage("Both TCP and USB are disable, default enable usb"); + enableUsb = true; + } + + WRITE_LOG(LOG_DEBUG, "flashd main run"); + HdcDaemon daemon(false); + daemon.InitMod(enableTcp, enableUsb); +#ifndef UPDATER_UT + daemon.WorkerPendding(); +#endif + return 0; +} +} diff --git a/services/flashd/flash_service.cpp b/services/flashd/flash_service.cpp new file mode 100755 index 00000000..1cd136b5 --- /dev/null +++ b/services/flashd/flash_service.cpp @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "flash_service.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "blockdevice.h" +#include "fs_manager/mount.h" +#include "package/pkg_manager.h" +#include "securec.h" +#include "updater/updater.h" +#include "updater/updater_const.h" +#include "utils.h" + +using namespace hpackage; +using namespace updater; + +namespace flashd { +FlashService::~FlashService() +{ + for (auto part : partitions_) { + printf("LoadBlockDevice %s \n", part->GetPartitionName().c_str()); + delete part; + } + partitions_.clear(); + for (auto dev : blockDevices_) { + delete dev; + } + blockDevices_.clear(); +} + +int FlashService::LoadSysDevice() +{ + if (loadSysDevice_) { + return 0; + } + return LoadBlockDevice("/dev/block"); +} + +int FlashService::DoUpdate(const std::string &packageName) +{ + int ret = 0; + FLASHING_LOGI("DoUpdate packageName %s", packageName.c_str()); + FLASHING_CHECK(access(packageName.c_str(), 0) == 0, + return FLASHING_IMAGE_INVALID, "Invalid package %s for update", packageName.c_str()); + ret = updater::IsSpaceCapacitySufficient(packageName); + if (ret == UPDATE_SPACE_NOTENOUGH) { + RecordMsg(updater::ERROR, "Free space is not enough"); + return FLASHING_SPACE_NOTENOUGH; + } + FLASHING_LOGI("Check space for packageName %s success", packageName.c_str()); + + uint64_t pkgLen = 0; + PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); + FLASHING_CHECK(pkgManager != nullptr, return FLASHING_PACKAGE_INVALID, "Failed to GetPackageInstance"); + pkgManager->SetPkgDecodeProgress([&](int type, size_t writeDataLen, const void *context) { + pkgLen += writeDataLen; + PostProgress(UPDATEMOD_UPDATE, writeDataLen, context); + }); + std::vector components; + ret = pkgManager->LoadPackage(packageName, utils::GetCertName(), components); + FLASHING_CHECK(ret == PKG_SUCCESS, PkgManager::ReleasePackageInstance(pkgManager); + RecordMsg(updater::ERROR, "Can not load package %s", packageName.c_str()); + return FLASHING_PACKAGE_INVALID, "Failed to load package %s", packageName.c_str()); +#ifndef LOCAL_SUPPORT + ret = updater::ExecUpdate(pkgManager, 0, + [&](const char *cmd, const char *content) { + if (strncmp(cmd, "data", strlen(cmd)) == 0) { + size_t dataLen = std::stoll(content); + PostProgress(UPDATEMOD_UPDATE, dataLen, nullptr); + } + }); +#endif + FLASHING_LOGI("Load packageName %s success %llu", packageName.c_str(), pkgLen); + PkgManager::ReleasePackageInstance(pkgManager); + return ret; +} + +int FlashService::DoFlashPartition(const std::string &fileName, const std::string &partition) +{ + int ret = CheckOperationPermission(flashd::UPDATEMOD_FLASH, partition); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Forbit to flash partition %s", partition.c_str()); + return FLASHING_NOPERMISSION, "Forbit to flash partition %s", partition.c_str()); + + ret = LoadSysDevice(); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Can not read device information"); + return FLASHING_PART_NOEXIST, "Failed to load partition"); + + FLASHING_LOGI("DoFlashPartition partition %s image:%s", partition.c_str(), fileName.c_str()); + PartitionPtr part = GetPartition(partition); + FLASHING_CHECK(part != nullptr, + RecordMsg(updater::ERROR, "Can not find partition %s", partition.c_str()); + return FLASHING_PART_NOEXIST, "Failed to get partition %s", partition.c_str()); + return part->DoFlash(fileName); +} + +int FlashService::GetPartitionPath(const std::string &partition, std::string ¶titionPath) +{ + int ret = CheckOperationPermission(flashd::UPDATEMOD_FLASH, partition); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Forbit to flash partition %s", partition.c_str()); + return FLASHING_NOPERMISSION, "Forbit to flash partition %s", partition.c_str()); + + ret = LoadSysDevice(); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Can not read device information"); + return FLASHING_PART_NOEXIST, "Failed to load partition"); + + FLASHING_LOGI("DoFlashPartition partition %s", partition.c_str()); + PartitionPtr part = GetPartition(partition); + FLASHING_CHECK(part != nullptr, + RecordMsg(updater::ERROR, "Can not find partition %s", partition.c_str()); + return FLASHING_PART_NOEXIST, "Failed to get partition %s", partition.c_str()); + paratitionPath = part->GetPartitionPath(); + return 0; +} + +int FlashService::DoErasePartition(const std::string &partition) +{ + int ret = CheckOperationPermission(flashd::UPDATEMOD_ERASE, partition); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Forbit to erase partition %s", partition.c_str()); + return FLASHING_NOPERMISSION, "Forbit to erase partition %s", partition.c_str()); + + ret = LoadSysDevice(); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Can not read device information"); + return FLASHING_PART_NOEXIST, "Failed to load partition"); + + FLASHING_LOGI("DoErasePartition partition %s ", partition.c_str()); + PartitionPtr part = GetPartition(partition); + FLASHING_CHECK(part != nullptr, + RecordMsg(updater::ERROR, "Can not find partition %s", partition.c_str()); + return FLASHING_PART_NOEXIST, "Failed to get partition %s", partition.c_str()); + return part->DoErase(); +} + +int FlashService::DoFormatPartition(const std::string &partition, const std::string &fsType) +{ + int ret = CheckOperationPermission(flashd::UPDATEMOD_FORMAT, partition); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Forbit to format partition %s", partition.c_str()); + return FLASHING_NOPERMISSION, "Forbit to format partition %s", partition.c_str()); + + ret = LoadSysDevice(); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Can not read device information"); + return FLASHING_PART_NOEXIST, "Failed to load partition"); + PartitionPtr part = GetPartition(partition); + FLASHING_CHECK(part != nullptr, + RecordMsg(updater::ERROR, "Can not find partition %s", partition.c_str()); + return FLASHING_PART_NOEXIST, "Failed to get partition %s", partition.c_str()); + if (part->IsOnlyErase()) { + FLASHING_LOGI("DoFormatPartition format partition %s", partition.c_str()); + return part->DoErase(); + } + FLASHING_LOGI("DoFormatPartition partition %s fsType:%s", partition.c_str(), fsType.c_str()); + return part->DoFormat(fsType); +} + +int FlashService::DoResizeParatiton(const std::string &partition, uint32_t blocks) +{ + int ret = CheckOperationPermission(flashd::UPDATEMOD_UPDATE, partition); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Forbit to resize partition %s", partition.c_str()); + return FLASHING_NOPERMISSION, "Forbit to resize partition %s", partition.c_str()); + + ret = LoadSysDevice(); + FLASHING_CHECK(ret == 0, + RecordMsg(updater::ERROR, "Can not read device information"); + return FLASHING_PART_NOEXIST, "Failed to load partition"); + + PartitionPtr part = GetPartition(partition); + FLASHING_CHECK(part != nullptr, + RecordMsg(updater::ERROR, "Can not find partition %s", partition.c_str()); + return FLASHING_PART_NOEXIST, "Failed to get partition %s", partition.c_str()); + return part->DoResize(blocks); +} + +PartitionPtr FlashService::GetPartition(const std::string &partition) const +{ + const std::string partName = GetPartNameByAlias(partition); + for (auto part : partitions_) { + if (partName.compare(part->GetPartitionName()) == 0) { + return part; + } + } + return nullptr; +} + +int FlashService::LoadBlockDevice(const std::string &fileDir) +{ + std::vector partitionsName {}; + struct stat dirStat = {}; + int ret = stat(fileDir.c_str(), &dirStat); + FLASHING_CHECK(ret != -1 && S_ISDIR(dirStat.st_mode), return -1, "Invlid dir %s", fileDir.c_str()); + + std::vector buffer(DEVICE_PATH_SIZE, 0); + struct dirent *entry = nullptr; + DIR *dir = opendir(fileDir.c_str()); + while ((entry = readdir(dir)) != nullptr) { + if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) { + continue; + } + std::string devPath = fileDir + "/" + entry->d_name; + if (entry->d_type == 10) { // 10 link 文件 + readlink(devPath.c_str(), buffer.data(), DEVICE_PATH_SIZE); + devPath = fileDir + "/" + buffer.data(); + memset_s(buffer.data(), DEVICE_PATH_SIZE, 0, DEVICE_PATH_SIZE); + } + ret = stat(devPath.c_str(), &dirStat); + FLASHING_CHECK(ret != -1, break, "Invlid dir %s %s", devPath.c_str(), strerror(errno)); + uint32_t devMajor = major(dirStat.st_rdev); + uint32_t devMinor = minor(dirStat.st_rdev); + if (devMajor == LOOP_MAJOR) { + continue; + } + ret = 0; + if (SCSI_BLK_MAJOR(devMajor)) { + if ((devMinor % 0x10) == 0) { + ret = AddNewBlockDevice(DeviceType::DEVICE_SCSI, devPath); + } else { + partitionsName.push_back(devPath); + } + } else if (devMajor == SDMMC_MAJOR) { + if (devMinor % 0x08 == 0) { + ret = AddNewBlockDevice(DeviceType::DEVICE_EMMC, devPath); + } else { + partitionsName.push_back(devPath); + } + } + FLASHING_CHECK(ret == 0, break, "Failed to add device %s", devPath.c_str()); + } + closedir(dir); + FLASHING_CHECK(ret == 0, return -1, "Failed to add device %s", fileDir.c_str()); + ret = LoadPartition(partitionsName); + loadSysDevice_ = true; + return ret; +} + +int FlashService::LoadPartition(std::vector &partitionsNames) +{ + std::sort(std::begin(partitionsNames), std::end(partitionsNames), std::less()); + for (auto device : blockDevices_) { + for (std::string path : partitionsNames) { + std::string name = GetBaseName(path); + if (strncmp(name.c_str(), device->GetDeviceName().c_str(), device->GetDeviceName().size()) != 0) { + continue; + } + AddNewPartition(path, device); + } + } + return 0; +} + +int FlashService::AddNewPartition(const std::string &path, BlockDevicePtr device) +{ + std::string name = GetBaseName(path); + PartitionPtr part = new Partition(name, GetRealPath(path), device, this); + FLASHING_CHECK(part != nullptr, return -1, "Failed to create partition %s", path.c_str()); + int ret = part->Load(); + FLASHING_CHECK(ret == 0, delete part; + return -1, "Failed to create partition %s", path.c_str()); + partitions_.push_back(part); + return 0; +} + +int FlashService::AddNewBlockDevice(DeviceType type, const std::string &devPath) +{ + BlockDevicePtr device = new BlockDevice(type, GetRealPath(devPath)); + FLASHING_CHECK(device != nullptr, return -1, "Failed to create device %s", devPath.c_str()); + int ret = device->Load(); + FLASHING_CHECK(ret == 0, delete device; + return 0, "Failed to create device %s", devPath.c_str()); + blockDevices_.push_back(device); + return 0; +} + +std::string FlashService::ReadSysInfo(const std::string &path, const std::string &type, std::vector &table) +{ + std::string returnStr; + auto file = std::unique_ptr(fopen(path.c_str(), "r"), fclose); + FLASHING_CHECK(file != nullptr, return "", "Failed to open %s", path.c_str()); + std::vector buffer(LINE_BUFFER_SIZE, 0); + while (fgets(buffer.data(), LINE_BUFFER_SIZE, file.get()) != nullptr) { + if (type == "uevent") { + table.push_back(buffer.data()); + } else if (type == "start") { + returnStr = std::string(buffer.data()); + break; + } else if (type == "size") { + returnStr = std::string(buffer.data()); + break; + } else if (type == "partition") { + returnStr = std::string(buffer.data()); + break; + } + memset_s(buffer.data(), LINE_BUFFER_SIZE, 0, LINE_BUFFER_SIZE); + } + return returnStr; +} + +std::string FlashService::GetParamFromTable(const std::vector &table, const std::string ¶m) +{ + for (std::string line : table) { + std::string::size_type pos = line.find(param); + if (pos != std::string::npos) { + return line.substr(param.size(), line.size() - 1 - param.size()); + } + } + return ""; +} + +int FlashService::ExecCommand(const std::vector &cmds) +{ + std::vector extractedCmds; + for (const auto &cmd : cmds) { + extractedCmds.push_back(const_cast(cmd.c_str())); + } + extractedCmds.push_back(nullptr); + pid_t pid = fork(); + if (pid < 0) { + FLASHING_CHECK(0, return -1, "Failed to fork %d error:%d", pid, errno); + return errno; + } + if (pid == 0) { + execv(extractedCmds[0], extractedCmds.data()); + exit(0x7f); // 0x7f exit code + } + int status; + waitpid(pid, &status, 0); + if (WEXITSTATUS(status) != 0 || !WIFEXITED(status)) { + return WEXITSTATUS(status); + } + return 0; +} + +void FlashService::RecordMsg(uint8_t level, const char *msg, ...) +{ + errorLevel_ = level; + va_list vaArgs; + va_start(vaArgs, msg); + std::vector zc(MAX_SIZE_BUF); + const int retSize = vsnprintf_s(zc.data(), MAX_SIZE_BUF, zc.size() - 1, msg, vaArgs); + if (retSize >= 0) { + errorMsg_ = std::string(zc.data(), retSize); + } + va_end(vaArgs); +} + +void FlashService::PostProgress(uint32_t type, size_t dataLen, const void *context) const +{ + if (progressor_ != nullptr) { + progressor_(type, dataLen, context); + } +} + +int FlashService::CheckOperationPermission(int type, const std::string &partition) const +{ + if (type >= UPDATEMOD_MAX) { + return 1; + } + std::vector forbitPartName[] = { + {}, // updater + {"updater"}, // flash + {"updater", "boot", "kernel"}, // erase + {"updater", "boot", "kernel"} // format + }; + if (forbitPartName[type].size() == 0) { + return 0; + } + const std::string partName = GetPartNameByAlias(partition); + auto it = std::find (forbitPartName[type].begin(), forbitPartName[type].end(), partName); + return it != forbitPartName[type].end(); +} + +const std::string FlashService::GetBaseName(const std::string &path) +{ + std::string::size_type pos = path.find_last_of('/') + 1; + return path.substr(pos, path.size() - pos); +} + +const std::string FlashService::GetPathRoot(const std::string &path) +{ + std::string::size_type pos = path.find_first_of('/', 1); + return path.substr(0, pos); +} + +const std::string FlashService::GetPartNameByAlias(const std::string &alias) +{ + std::map> partNameMap = { + { "userdata", { "data", "/data", "userdata" } }, + { "system", { "system", "/system" } }, + { "vendor", { "vendor", "/vendor" } }, + { "misc", { "misc", "/misc" } }, + { "updater", { "updater", "/updater" } }, + { "kernel", { "boot" } }, // image + { "boot", { "fastboot" } }, // fastboot + }; + for (auto iter = partNameMap.begin(); iter != partNameMap.end(); iter++) { + for (auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) { + if (*iter2 == alias) { + return iter->first; + } + } + } + return alias; +} + +const std::string FlashService::GetRealPath(const std::string &path) +{ + std::vector realPath(DEVICE_PATH_SIZE, 0); + return realpath(path.c_str(), realPath.data()); +} + +bool FlashService::CheckFreeSpace(const std::string &root, uint32_t blocks) +{ + struct statvfs64 vfs {}; + int ret = statvfs64(root.c_str(), &vfs); + FLASHING_CHECK(ret >= 0, return false, "Failed to statvfs %s", root.c_str()); + if (static_cast(vfs.f_bsize) == DEFAULT_BLOCK_SIZE) { + return static_cast(vfs.f_bfree) < static_cast(blocks); + } + return static_cast(vfs.f_bfree) < (blocks / static_cast(vfs.f_bsize)) * DEFAULT_BLOCK_SIZE; +} + +static std::string GetValueFromParam(const std::vector ¶ms, + const std::string ¶mType, const std::string &defValue) +{ + std::string ret = defValue; + for (size_t i = 0; i < params.size(); i++) { + if (paramType.compare(params[i]) == 0) { + if (i < (params.size() - 1)) { + ret = params[i + 1]; + } else { + ret = "true"; + } + } + } + return ret; +} + +static bool FilterParam(const std::string ¶m, const std::vector &filter) +{ + auto iter = filter.begin(); + while (iter != filter.end()) { + if (param.compare(*iter) == 0) { + return true; + } + iter++; + } + return false; +} + +static int GetCmdParam(uint8_t type, const std::string &origString, + const std::vector &filter, std::vector &resultStrings) +{ + static uint32_t paramMinNumber[flashd::UPDATEMOD_MAX + 1] = { 1, 2, 2, 2, 0 }; + std::string::size_type p1 = 0; + std::string::size_type p2 = origString.find(" "); + + while (p2 != std::string::npos) { + if (p2 == p1) { + ++p1; + p2 = origString.find(" ", p1); + continue; + } + + std::string param = origString.substr(p1, p2 - p1); + if (!FilterParam(param, filter)) { + resultStrings.push_back(param); + } + p1 = p2 + 1; + p2 = origString.find(" ", p1); + } + + if (p1 != origString.size()) { + std::string param = origString.substr(p1); + if (!FilterParam(param, filter)) { + resultStrings.push_back(param); + } + } + FLASHING_CHECK((resultStrings.size() >= paramMinNumber[type]) && (type <= flashd::UPDATEMOD_MAX), + return FLASHING_ARG_INVALID, "Invalid param for %d cmd %s", type, origString.c_str()); + return 0; +} + +int CreateFlashInstance(FlashHandle *handle, std::string &errorMsg, ProgressFunction progressor) +{ + FLASHING_CHECK(handle != nullptr, return FLASHING_ARG_INVALID, "Invalid handle"); + flashd::FlashService *flash = new flashd::FlashService(errorMsg, progressor); + if (flash == nullptr) { + FLASHING_LOGE("Failed to create flash service"); + errorMsg = "Create instance fail"; + return FLASHING_SYSTEM_ERROR; + } + *handle = static_cast(flash); + return 0; +} + +int DoUpdaterPrepare(FlashHandle handle, uint8_t type, const std::string &cmdParam, std::string &filePath) +{ + FLASHING_CHECK(handle != nullptr, return FLASHING_ARG_INVALID, "Invalid handle for %d", type); + flashd::FlashService *flash = static_cast(handle); + + std::vector params {}; + int ret = GetCmdParam(type, cmdParam, { "-f" }, params); + FLASHING_CHECK(ret == 0, flash->RecordMsg(updater::ERROR, "Invalid param for %d", type); + return FLASHING_ARG_INVALID, "Invalid param for %d", type); + FLASHING_DEBUG("DoUpdaterPrepare type: %d param %s filePath %s", type, cmdParam.c_str(), filePath.c_str()); + switch (type) { + case flashd::UPDATEMOD_UPDATE: { + filePath = FLASHD_FILE_PATH + filePath; + // 检查剩余分区大小,扩展分区 + const std::string root = flashd::FlashService::GetPathRoot(FLASHD_FILE_PATH); + ret = MountForPath(root); + FLASHING_CHECK(ret == 0, + flash->RecordMsg(updater::ERROR, "Failed to mount data paratition for %s", filePath.c_str()); + return FLASHING_INVALID_SPACE, "Failed to mount data paratition for %s", filePath.c_str()); + + ret = flash->DoResizeParatiton(root, MIN_BLOCKS_FOR_UPDATE); + FLASHING_CHECK(ret == 0, return ret, "Failed to resize partition"); + if (access(FLASHD_FILE_PATH.c_str(), F_OK) == -1) { + mkdir(FLASHD_FILE_PATH.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + } + break; + } + case flashd::UPDATEMOD_FLASH: { + ret = flash->GetPartitionPath(params[0], filePath); + break; + } + default: + ret = flashd::FLASHING_SYSTEM_ERROR; + break; + } + return ret; +} + +int DoUpdaterFlash(FlashHandle handle, uint8_t type, const std::string &cmdParam, const std::string &filePath) +{ + FLASHING_CHECK(handle != nullptr, return FLASHING_ARG_INVALID, "Invalid handle for %d", type); + flashd::FlashService *flash = static_cast(handle); + + std::vector params {}; + int ret = GetCmdParam(type, cmdParam, {"-f"}, params); + FLASHING_CHECK(ret == 0, + flash->RecordMsg(updater::ERROR, "Invalid param for %d", type); + return FLASHING_ARG_INVALID, "Invalid param for %d", type); + FLASHING_DEBUG("DoUpdaterFlash type: %d param %s filePath %s", type, cmdParam.c_str(), filePath.c_str()); + switch (type) { + case flashd::UPDATEMOD_UPDATE: { + ret = flash->DoUpdate(filePath); + unlink(filePath.c_str()); + break; + } + case flashd::UPDATEMOD_ERASE: + FLASHING_CHECK(params.size() > 1, return FLASHING_ARG_INVALID, "Invalid param size for erase"); + ret = flash->DoErasePartition(params[1]); + break; + case flashd::UPDATEMOD_FORMAT: { + std::string fsType = GetValueFromParam(params, "-t", "ext4"); + FLASHING_CHECK(params.size() > 1, return FLASHING_ARG_INVALID, "Invalid param size for format"); + ret = flash->DoFormatPartition(params[1], fsType); + break; + } + default: + ret = flashd::FLASHING_SYSTEM_ERROR; + break; + } + return ret; +} + +int DoUpdaterFinish(FlashHandle handle, uint8_t type, const std::string &partition) +{ + FLASHING_CHECK(handle != nullptr, return FLASHING_ARG_INVALID, "Invalid handle for %d", type); + FLASHING_DEBUG("DoUpdaterFinish type: %d %s", type, partition.c_str()); + updater::PostUpdater(); + switch (type) { + case flashd::UPDATEMOD_UPDATE: { + utils::DoReboot(""); + break; + } + default: + break; + } + return 0; +} +} // namespace flashd diff --git a/services/flashd/flash_service.h b/services/flashd/flash_service.h new file mode 100755 index 00000000..e9420784 --- /dev/null +++ b/services/flashd/flash_service.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef FLASHING_H +#define FLASHING_H +#include +#include +#include +#include +#include "blockdevice.h" +#include "partition.h" +#include "updater/updater.h" + +// Just update-mode use +namespace flashd { +class FlashService { +public: + FlashService(std::string &errorMsg, ProgressFunction progressor) + : errorMsg_(errorMsg), progressor_(progressor) {} + explicit FlashService(std::string &errorMsg) : errorMsg_(errorMsg), progressor_(nullptr) {} + ~FlashService(); + + int DoUpdate(const std::string &packageName); + int DoFlashPartition(const std::string &fileName, const std::string &partition); + int DoErasePartition(const std::string &partition); + int DoFormatPartition(const std::string &partition, const std::string &fsType); + int GetPartitionPath(const std::string &partition, std::string ¶titionPath); + int DoResizeParatiton(const std::string &partition, uint32_t blocks); + + int LoadSysDevice(); + PartitionPtr GetPartition(const std::string &partition) const; + + void PostProgress(uint32_t type, size_t dataLen, const void *context) const; + void RecordMsg(uint8_t level, const char *msg, ...); + uint8_t GetErrorLevel() const + { + return errorLevel_; + } + + static std::string ReadSysInfo(const std::string &path, const std::string &type, std::vector &table); + static std::string GetParamFromTable(const std::vector &table, const std::string ¶m); + static int ExecCommand(const std::vector &cmds); + + static const std::string GetBaseName(const std::string &path); + static const std::string GetPathRoot(const std::string &path); + static const std::string GetRealPath(const std::string &path); + static const std::string GetPartNameByAlias(const std::string &alias); + static bool CheckFreeSpace(const std::string &root, uint32_t blocks); +private: + int LoadBlockDevice(const std::string &fileDir); + int LoadPartition(std::vector &partitionsNames); + + int AddNewBlockDevice(DeviceType type, const std::string &devPath); + int AddNewPartition(const std::string &path, BlockDevicePtr device); + + int CheckOperationPermission(int type, const std::string &partition) const; + std::string &errorMsg_; + ProgressFunction progressor_; + uint8_t errorLevel_ = 0; + bool loadSysDevice_ = false; + std::vector blockDevices_; + std::vector partitions_; +}; +} +#endif // FLASHING_H \ No newline at end of file diff --git a/services/flashd/flash_utils.h b/services/flashd/flash_utils.h new file mode 100755 index 00000000..0f6a415d --- /dev/null +++ b/services/flashd/flash_utils.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef FLASHING_UTILS_H +#define FLASHING_UTILS_H +#include + +#include "flashd/flashd.h" +#include "log/log.h" +#include "securec.h" + +namespace flashd { +#define FLASHING_LOGE(format, ...) Logger(updater::ERROR, (__FILE_NAME__), (__LINE__), format, ##__VA_ARGS__) +#define FLASHING_DEBUG(format, ...) Logger(updater::DEBUG, (__FILE_NAME__), (__LINE__), format, ##__VA_ARGS__) +#define FLASHING_LOGI(format, ...) Logger(updater::INFO, (__FILE_NAME__), (__LINE__), format, ##__VA_ARGS__) +#define FLASHING_LOGW(format, ...) Logger(updater::WARNING, (__FILE_NAME__), (__LINE__), format, ##__VA_ARGS__) + +#define FLASHING_CHECK(retCode, exper, ...) \ + if (!(retCode)) { \ + FLASHING_LOGE(__VA_ARGS__); \ + exper; \ + } + +static constexpr size_t BUFFER_SIZE = 64 * 1024; +static constexpr uint32_t LOOP_MAJOR = 7; +static constexpr uint32_t SCSI_CDROM_MAJOR = 11; +static constexpr uint32_t SCSI_DISK0_MAJOR = 8; +static constexpr uint32_t SDMMC_MAJOR = 179; +static constexpr uint32_t DEVICE_PATH_SIZE = 256; +static constexpr uint32_t LINE_BUFFER_SIZE = 256; +static constexpr size_t SECTOR_SIZE_DEFAULT = 512; +#define SCSI_BLK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR) + +class FlashService; +using FlashingPtr = FlashService *; +} // namespace flashd +#endif // FLASHING_UTILS_H diff --git a/services/flashd/host/host_updater.cpp b/services/flashd/host/host_updater.cpp new file mode 100755 index 00000000..4de625d3 --- /dev/null +++ b/services/flashd/host/host_updater.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "host_updater.h" +#include "common.h" +#include "transfer.h" +#include "serial_struct.h" + +namespace Hdc { +static const int PERCENT_FINISH = 100; +static const uint32_t PERCENT_CLEAR = ((uint32_t)-1); +HostUpdater::HostUpdater(HTaskInfo hTaskInfo) : HdcTransferBase(hTaskInfo) +{ + commandBegin = CMD_UPDATER_BEGIN; + commandData = CMD_UPDATER_DATA; +} + +HostUpdater::~HostUpdater() {} + +void HostUpdater::RunQueue(CtxFile &context) +{ + refCount++; + context.localPath = context.taskQueue.back(); + uv_fs_open(loopTask, &context.fsOpenReq, context.localPath.c_str(), O_RDONLY, 0, OnFileOpen); + context.master = true; +} + +bool HostUpdater::BeginTransfer(CtxFile &context, + const std::string &function, const char *payload, int minParam, int fileIndex) +{ + int argc = 0; + char **argv = Base::SplitCommandToArgs(payload, &argc); + if (argv == nullptr || argc < minParam || fileIndex >= argc) { + LogMsg(MSG_FAIL, "Invalid param for cmd \"%s\"", function.c_str()); + delete[]((char *)argv); + return false; + } + int maxParam = minParam; + if (strstr(payload, "-f") != nullptr) { + maxParam += 1; + } + if (argc != maxParam) { + LogMsg(MSG_FAIL, "Invalid param for cmd \"%s\"", function.c_str()); + delete[]((char *)argv); + return false; + } + + context.transferConfig.functionName = function; + context.transferConfig.options = payload; + if (strcmp(argv[fileIndex], "-f") == 0) { + context.localPath = argv[fileIndex + 1]; + } else { + context.localPath = argv[fileIndex]; + } + + if (MatchPackageExtendName(context.localPath, ".img")) { + context.transferConfig.compressType = COMPRESS_NONE; + } else if (function == CMDSTR_FLASH_PARTITION) { + context.transferConfig.compressType = COMPRESS_NONE; + } else if (MatchPackageExtendName(context.localPath, ".bin")) { + context.transferConfig.compressType = COMPRESS_NONE; + } else if (!(MatchPackageExtendName(context.localPath, ".zip") || + MatchPackageExtendName(context.localPath, ".lz4") || + MatchPackageExtendName(context.localPath, ".gz2"))) { + LogMsg(MSG_FAIL, "Invaid file \"%s\" for cmd \"%s\"", context.localPath.c_str(), function.c_str()); + delete[]((char *)argv); + return false; + } + + WRITE_LOG(LOG_DEBUG, "BeginTransfer function: %s localPath: %s command: %s ", + context.transferConfig.functionName.c_str(), context.localPath.c_str(), payload); + // check path + bool ret = Base::CheckDirectoryOrPath(context.localPath.c_str(), true, true); + if (!ret) { + LogMsg(MSG_FAIL, "Invaid file \"%s\" for cmd \"%s\"", context.localPath.c_str(), function.c_str()); + delete[]((char *)argv); + return false; + } + context.taskQueue.push_back(context.localPath); + RunQueue(context); + return true; +} + +std::string HostUpdater::GetFileName(const std::string &fileName) const +{ + int32_t pos = fileName.find_last_of('/'); + if (pos < 0) { + pos = fileName.find_last_of('\\'); + } + return fileName.substr(pos + 1, fileName.size()); +} + +void HostUpdater::CheckMaster(CtxFile *context) +{ + uv_fs_t fs; + Base::ZeroStruct(fs.statbuf); + uv_fs_fstat(nullptr, &fs, context->fsOpenReq.result, nullptr); + context->transferConfig.fileSize = fs.statbuf.st_size; + uv_fs_req_cleanup(&fs); + + WRITE_LOG(LOG_DEBUG, "CheckMaster %s %llu", context->transferConfig.functionName.c_str(), fs.statbuf.st_size); + context->transferConfig.optionalName = GetFileName(context->localPath); + std::string bufString = SerialStruct::SerializeToString(context->transferConfig); + + const uint64_t verdorSize = static_cast(1024 * 1024) * 256; + const uint64_t systemSize = static_cast(1024 * 1024) * 1500; + const uint64_t minSize = static_cast(1024 * 1024) * 10; + uint64_t realSize = verdorSize; + if (fs.statbuf.st_size > minSize) { + realSize += systemSize; + } + std::vector buffer(sizeof(realSize) + bufString.size()); + int ret = memcpy_s(buffer.data(), buffer.size(), &realSize, sizeof(realSize)); + int ret2 = memcpy_s(buffer.data() + sizeof(realSize), buffer.size(), bufString.c_str(), bufString.size()); + if ((ret == 0) && (ret2 == 0)) { + SendToAnother(CMD_UPDATER_CHECK, (uint8_t *)buffer.data(), buffer.size()); + } +} + +bool HostUpdater::CheckCmd(const std::string &function, const char *payload, int param) +{ + int argc = 0; + char **argv = Base::SplitCommandToArgs(payload, &argc); + if (argv == nullptr) { + LogMsg(MSG_FAIL, "Can not parser cmd \"%s\"", function.c_str()); + return false; + } + delete[]((char *)argv); + if (argc < param) { + LogMsg(MSG_FAIL, "Invalid param for cmd \"%s\"", function.c_str()); + return false; + } + + int maxParam = param; + if (strstr(payload, "-f") != nullptr) { + maxParam += 1; + } + if (strstr(payload, "-t") != nullptr) { + maxParam += 1; + maxParam += 1; + } + if (argc != maxParam) { + LogMsg(MSG_FAIL, "Invalid param for cmd \"%s\"", function.c_str()); + return false; + } + return true; +} + +bool HostUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + const int cmdFroErase = 2; + const int cmdFroFormat = 2; + if (!HdcTransferBase::CommandDispatch(command, payload, payloadSize)) { + return false; + } + bool ret = true; + switch (command) { + case CMD_UPDATER_BEGIN: { + std::string s(" Processing: 0%%"); + bSendProgress = true; + SendRawData(reinterpret_cast(s.data()), s.size()); + break; + } + case CMD_UPDATER_UPDATE_INIT: + ret = BeginTransfer(ctxNow, CMDSTR_UPDATE_SYSTEM, reinterpret_cast(payload), 1, 0); + break; + case CMD_UPDATER_FLASH_INIT: + ret = BeginTransfer(ctxNow, CMDSTR_FLASH_PARTITION, + reinterpret_cast(payload), 2, 1); // 2 cmd min param for flash + break; + case CMD_UPDATER_FINISH: + ret = CheckUpdateContinue(command, payload, payloadSize); + break; + case CMD_UPDATER_ERASE: { + if (!CheckCmd(CMDSTR_ERASE_PARTITION, reinterpret_cast(payload), cmdFroErase)) { + return false; + } + SendToAnother(CMD_UPDATER_ERASE, payload, payloadSize); + ctxNow.taskQueue.push_back(reinterpret_cast(payload)); + break; + } + case CMD_UPDATER_FORMAT: { + if (!CheckCmd(CMDSTR_FORMAT_PARTITION, reinterpret_cast(payload), cmdFroFormat)) { + return false; + } + SendToAnother(CMD_UPDATER_FORMAT, payload, payloadSize); + ctxNow.taskQueue.push_back(reinterpret_cast(payload)); + break; + } + case CMD_UPDATER_PROGRESS: + if (payloadSize >= (int)sizeof(uint32_t)) { + ProcessProgress(*(uint32_t *)payload); + } + break; + default: + break; + } + return ret; +} + +void HostUpdater::ProcessProgress(uint32_t percentage) +{ + if (!bSendProgress) { + return; + } + std::string backStr = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; + std::string breakStr = "\n"; + WRITE_LOG(LOG_INFO, "ProcessProgress %d", percentage); + const int bufferSize = 128; + std::vector buffer(bufferSize); + if (percentage == PERCENT_CLEAR) { // clear + SendRawData(reinterpret_cast(backStr.data()), backStr.size()); + SendRawData(reinterpret_cast(breakStr.data()), breakStr.size()); + bSendProgress = false; + return; + } + int len = sprintf_s(buffer.data(), buffer.size() - 1, "%s Processing: %3d%%", backStr.c_str(), percentage); + if (len <= 0) { + return; + } + SendRawData(reinterpret_cast(buffer.data()), len); + if (percentage == PERCENT_FINISH) { + SendRawData(reinterpret_cast(breakStr.data()), breakStr.size()); + bSendProgress = false; + } +} + +bool HostUpdater::CheckUpdateContinue(const uint16_t command, const uint8_t *payload, int payloadSize) +{ + if (static_cast(payloadSize) < sizeof(uint16_t)) { + return false; + } + MessageLevel level = (MessageLevel)payload[1]; + if ((level == MSG_OK) && bSendProgress) { + ProcessProgress(PERCENT_FINISH); + } + std::string info((char*)(payload + sizeof(uint16_t)), payloadSize - sizeof(uint16_t)); + if (!info.empty()) { + LogMsg(level, "%s", info.c_str()); + } + WRITE_LOG(LOG_DEBUG, "CheckUpdateContinue %d %s", level, info.c_str()); + ctxNow.taskQueue.pop_back(); + if (singalStop || !ctxNow.taskQueue.size()) { + return false; + } + RunQueue(ctxNow); + return true; +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/host/host_updater.h b/services/flashd/host/host_updater.h new file mode 100755 index 00000000..08e5ec78 --- /dev/null +++ b/services/flashd/host/host_updater.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_HOST_UPDATER_H +#define HDC_HOST_UPDATER_H +#include "common.h" +#include "transfer.h" + +namespace Hdc { +class HostUpdater : public HdcTransferBase { +public: + explicit HostUpdater(HTaskInfo hTaskInfo); + virtual ~HostUpdater(); + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) override; + +private: + void CheckMaster(CtxFile *context) override; + + bool BeginTransfer(CtxFile &context, + const std::string &function, const char *payload, int minParam, int fileIndex); + bool CheckUpdateContinue(const uint16_t command, const uint8_t *payload, int payloadSize); + void RunQueue(CtxFile &context); + std::string GetFileName(const std::string &fileName) const; + void ProcessProgress(uint32_t percentage); +#ifdef UPDATER_UT + void LogMsg(MessageLevel level, const char *msg, ...) + { + va_list vaArgs; + va_start(vaArgs, msg); + string log = Base::StringFormat(msg, vaArgs); + va_end(vaArgs); + WRITE_LOG(LOG_DEBUG, "LogMsg %d %s", level, log.c_str()); + return; + } + void SendRawData(uint8_t *bufPtr, const int size) + { + WRITE_LOG(LOG_DEBUG, "SendRawData %d", size); + } + bool SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size) + { + WRITE_LOG(LOG_DEBUG, "SendToAnother command %d size %d", command, size); + return true; + } +#endif +private: + bool CheckCmd(const std::string &function, const char *payload, int param); + + bool bSendProgress = false; +}; +} +#endif \ No newline at end of file diff --git a/services/flashd/partition.cpp b/services/flashd/partition.cpp new file mode 100755 index 00000000..75d0f1d8 --- /dev/null +++ b/services/flashd/partition.cpp @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "partition.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "flash_service.h" +#include "utils.h" + +namespace flashd { +Partition::~Partition() +{ + if (fd_ != -1) { + close(fd_); + } +} + +int Partition::Load() +{ + std::vector table; + std::string info = ReadPartitionSysInfo(devName_, "partition", table); + FLASHING_CHECK(!info.empty(), return -1, "Can not get partition for %s", devName_.c_str()); + partNumber_ = atoi(info.c_str()); + + ReadPartitionSysInfo(devName_, "uevent", table); + info = FlashService::GetParamFromTable(table, "DEVNAME="); + FLASHING_CHECK(info == devName_, return -1, "Failed to check dev name %s %s", info.c_str(), devName_.c_str()); + + partName_ = FlashService::GetParamFromTable(table, "PARTNAME="); + if (partName_.empty()) { + partName_ = devName_; + } + int ret = Partition::GetMountInfo(); + FLASHING_LOGI("Partition info devName \"%s\" partPath_ \"%s\" partName_ \"%s\"", + devName_.c_str(), partPath_.c_str(), partName_.c_str()); + if (!mountPoint_.empty()) { + FLASHING_LOGI("Partition mount info mount \"%s\" fs %s flags: %s", + mountPoint_.c_str(), fsType_.c_str(), mountFlags_.c_str()); + } + return ret; +} + +int Partition::DoFlash(const std::string &fileName) +{ + int ret = Open(); + FLASHING_CHECK(ret == 0, return ret, "Can not open partiton %s for flash", partName_.c_str()); + + auto inputFd = open(fileName.c_str(), O_RDONLY); + FLASHING_CHECK(inputFd > 0, + flash_->RecordMsg(updater::ERROR, "Can not open image \"%s\" error: %s", fileName.c_str(), strerror(errno)); + return FLASHING_NOPERMISSION, "Can not open image \"%s\" error: %s", fileName.c_str(), strerror(errno)); + + struct stat st {}; + size_t fileSize = 1; + if (fstat(inputFd, &st) >= 0) { + fileSize = st.st_size; + } + + std::vector content(BUFFER_SIZE); + ssize_t readLen = read(inputFd, content.data(), content.size()); + FLASHING_CHECK(readLen >= 0, close(inputFd); + return FLASHING_PART_WRITE_ERROR, "Failed to flash data of len %d", readLen); + ret = WriteRowData(inputFd, fileSize, content, readLen); + close(inputFd); + FLASHING_CHECK(ret == 0, return ret, "Failed to write %s", fileName.c_str()); + FLASHING_LOGI("DoFlash partition %s image:%s success", partPath_.c_str(), fileName.c_str()); + return ret; +} + +int Partition::DoErase() +{ + int ret = Open(); + FLASHING_CHECK(ret == 0, return ret, "Can not open partiton %s for erase", partName_.c_str()); + + if (!IsBlockDevice(fd_)) { + return 0; + } + + uint64_t size = GetBlockDeviceSize(fd_); + FLASHING_LOGI("DoErase partition %s size %luM", partPath_.c_str(), size); + uint64_t range[2] = {0}; + range[1] = size; + ret = ioctl(fd_, BLKSECDISCARD, &range); + FLASHING_LOGI("DoErase partition %s ret %d", partPath_.c_str(), ret); + if (ret < 0) { + range[0] = 0; + range[1] = size; + ret = ioctl(fd_, BLKDISCARD, &range); + FLASHING_CHECK(ret >= 0, + flash_->RecordMsg(updater::ERROR, "Failed to erase \"%s\" error: %s", partName_.c_str(), strerror(errno)); + return ret, "Failed to erase %s error: %s", partName_.c_str(), strerror(errno)); + std::vector buffer(BLOCK_SIZE, 0); + ret = updater::utils::WriteFully(fd_, buffer.data(), buffer.size()); + FLASHING_CHECK(ret == 0, return FLASHING_PART_WRITE_ERROR, "Failed to flash data errno %d", errno); + fsync(fd_); + } + FLASHING_LOGI("DoErase partition %s erase success", partPath_.c_str()); + return 0; +} + +int Partition::DoFormat(const std::string &fsType) +{ + if (mountPoint_ == "/") { /* Can not format root */ + return 0; + } + int ret = DoUmount(); + FLASHING_CHECK(ret == 0, return FLASHING_PART_WRITE_ERROR, "Failed to umount partition"); + + std::vector formatCmds {}; + ret = BuildCommandParam(fsType, formatCmds); + FLASHING_CHECK(ret == 0, return FLASHING_PART_WRITE_ERROR, "Failed to get param"); + ret = FlashService::ExecCommand(formatCmds); + FLASHING_CHECK(ret == 0, + flash_->RecordMsg(updater::ERROR, "Failed to format \"%s\" error: %s", partName_.c_str(), strerror(ret)); + return FLASHING_PART_WRITE_ERROR, "Failed to format \"%s\" error: %s", partPath_.c_str(), strerror(ret)); + + fsType_ = fsType; + ret = DoMount(); + FLASHING_CHECK(ret == 0, + flash_->RecordMsg(updater::ERROR, "Failed to mount \"%s\" error: %s", partName_.c_str(), strerror(ret)); + return FLASHING_PART_WRITE_ERROR, "Failed to mount \"%s\"", partPath_.c_str()); + FLASHING_LOGI("DoFormat partition %s format %s success", partName_.c_str(), fsType_.c_str()); + return ret; +} + +int Partition::DoResize(uint32_t blocks) +{ + int ret = 0; + bool needResize = false; + if (!mountPoint_.empty()) { + needResize = FlashService::CheckFreeSpace(mountPoint_, blocks); + } else { + ret = Open(); + FLASHING_CHECK(ret == 0, return ret, "Can not open partiton %s for erase", partName_.c_str()); + uint64_t size = GetBlockDeviceSize(fd_); + FLASHING_LOGI("DoResise partition %s size %lu", partName_.c_str(), size); + close(fd_); + fd_ = -1; + uint64_t min = static_cast(DEFAULT_BLOCK_SIZE) * static_cast(blocks); + needResize = size < min; + } + if (!needResize) { + FLASHING_LOGI("No need to resize partition %s", partName_.c_str()); + return 0; + } + ret = DoUmount(); + FLASHING_CHECK(ret == 0, return FLASHING_PART_WRITE_ERROR, "Failed to umount partition"); + + std::vector formatCmds; + formatCmds.push_back(RESIZE_TOOL); + formatCmds.push_back(partPath_); + ret = FlashService::ExecCommand(formatCmds); + FLASHING_CHECK(ret == 0, + flash_->RecordMsg(updater::ERROR, "Failed to resize \"%s\" error: %s", partName_.c_str(), strerror(ret)); + return FLASHING_PART_WRITE_ERROR, "Failed to resize \"%s\" error: %s", partName_.c_str(), strerror(ret)); + ret = DoMount(); + FLASHING_CHECK(ret == 0, + flash_->RecordMsg(updater::ERROR, "Failed to mount \"%s\" error: %s", partName_.c_str(), strerror(ret)); + return FLASHING_PART_WRITE_ERROR, "Failed to mount \"%s\"", partPath_.c_str()); + FLASHING_LOGI("Resize partition %s success", partName_.c_str()); + return 0; +} + +int Partition::Open() +{ + if (fd_ != -1) { + return 0; + } + fd_ = open(partPath_.c_str(), O_RDWR); + FLASHING_CHECK(fd_ > 0, + flash_->RecordMsg(updater::ERROR, + "Can not open partiton \"%s\" error: %s", partName_.c_str(), strerror(errno)); + return FLASHING_NOPERMISSION, + "Can open partition %s error %s", partPath_.c_str(), strerror(errno)); + return 0; +} + +int Partition::WriteRowData(int inputFd, size_t fileSize, std::vector &buffer, size_t dataSize) +{ + size_t dataLen = dataSize; + size_t totalWrite = 0; + do { +#ifndef UPDATER_UT + ssize_t writeLen = write(fd_, buffer.data(), dataLen); +#else + ssize_t writeLen = dataLen; +#endif + FLASHING_CHECK(writeLen >= 0, + return FLASHING_PART_WRITE_ERROR, "Failed to write data of len %d", dataLen); + totalWrite += writeLen; + + // continue read and write + ssize_t ret = read(inputFd, buffer.data(), buffer.size()); + if (ret <= 0) { + break; + } + + flash_->PostProgress(UPDATEMOD_FLASH, dataSize, nullptr); + dataLen = ret; + } while (1); + fsync(fd_); + return 0; +} + +int Partition::IsBlockDevice(int fd) const +{ + struct stat st {}; + int ret = fstat(fd, &st); + if (ret < 0) { + return 0; + } + return S_ISBLK(st.st_mode); +} + +uint64_t Partition::GetBlockDeviceSize(int fd) const +{ + uint64_t size = 0; + int ret = ioctl(fd, BLKGETSIZE64, &size); + return (ret == 0) ? size : 0; +} + +std::string Partition::ReadPartitionSysInfo(const std::string &partition, + const std::string &type, std::vector &table) +{ + std::vector buffer(DEVICE_PATH_SIZE, 0); + int ret = snprintf_s(buffer.data(), DEVICE_PATH_SIZE, DEVICE_PATH_SIZE - 1, + "/sys/block/%s/%s/%s", device_->GetDeviceName().c_str(), partition.c_str(), type.c_str()); + FLASHING_CHECK(ret != -1, return "", "Failed to snprintf_s %s", device_->GetDeviceName().c_str()); + return FlashService::ReadSysInfo(buffer.data(), type, table); +} + +const std::string Partition::GetPartitionName() const +{ + return partName_; +} + +int Partition::GetMountInfo() +{ + auto file = std::unique_ptr(fopen("/proc/mounts", "r"), fclose); + FLASHING_CHECK(file != nullptr, return -1, "Failed to open mounts "); + std::vector buffer(LINE_BUFFER_SIZE, 0); + std::vector mount(DEVICE_PATH_SIZE, 0); + std::vector fsType(DEVICE_PATH_SIZE, 0); + std::vector dev(DEVICE_PATH_SIZE, 0); + std::vector flags(DEVICE_PATH_SIZE, 0); + while (fgets(buffer.data(), LINE_BUFFER_SIZE, file.get()) != nullptr) { + // clang-format off + int ret = sscanf_s(buffer.data(), "%255s %255s %255s %255s %*d %*d\n", + dev.data(), DEVICE_PATH_SIZE - 1, + mount.data(), DEVICE_PATH_SIZE - 1, + fsType.data(), DEVICE_PATH_SIZE - 1, + flags.data(), DEVICE_PATH_SIZE - 1); + // clang-format on + if (ret <= 0) { + break; + } + struct stat st {}; + if (lstat(dev.data(), &st) < 0) { + continue; + } + if (S_ISLNK(st.st_mode)) { + readlink(dev.data(), dev.data(), DEVICE_PATH_SIZE); + } + if (strncmp(dev.data(), partPath_.c_str(), partPath_.size()) == 0 || + (partName_ == "system" && strncmp(mount.data(), "/", strlen("/")) == 0)) { + mountPoint_.assign(mount.data()); + fsType_.assign(fsType.data()); + mountFlags_.assign(flags.data()); + break; + } + memset_s(buffer.data(), LINE_BUFFER_SIZE, 0, LINE_BUFFER_SIZE); + } + return 0; +} + +int Partition::DoUmount() +{ + if (mountPoint_.empty()) { + return 0; + } + int ret = umount2(mountPoint_.c_str(), MNT_FORCE); + FLASHING_CHECK(ret == 0, + flash_->RecordMsg(updater::ERROR, "Failed to umount \"%s\" error: %s", partName_.c_str(), strerror(errno)); + return FLASHING_PART_WRITE_ERROR, "Failed to umount \"%s\" error: %s", partName_.c_str(), strerror(errno)); + return ret; +} + +int Partition::DoMount() +{ + if (mountPoint_.empty()) { + return 0; + } + struct stat st {}; + int ret = lstat(mountPoint_.c_str(), &st); + FLASHING_CHECK(ret >= 0, return ret, "Failed to fstat %s error %s", mountPoint_.c_str(), strerror(errno)); + + if (S_ISLNK(st.st_mode)) { + unlink(mountPoint_.c_str()); + } + mkdir(mountPoint_.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + + // get mount flags + std::string data; + uint32_t flags = GetMountFlags(mountFlags_, data); + errno = 0; + while ((ret = mount(partPath_.c_str(), mountPoint_.c_str(), fsType_.c_str(), flags, data.c_str()) != 0)) { + if (errno == EAGAIN) { + continue; + } else { + break; + } + } + return ret; +} + +int Partition::BuildCommandParam(const std::string &fsType, std::vector &formatCmds) const +{ + std::map fsToolsMap = { + { "ext4", FORMAT_TOOL_FOR_EXT4 }, + { "f2fs", FORMAT_TOOL_FOR_F2FS }, + }; + auto it = fsToolsMap.find(fsType); + FLASHING_CHECK(it != fsToolsMap.end(), + flash_->RecordMsg(updater::ERROR, "Not support fs type %s", fsType.c_str()); + return FLASHING_FSTYPE_NOT_SUPPORT, "Not support fs type %s", fsType.c_str()); + + if (fsType == "ext4") { + formatCmds.push_back(it->second); + formatCmds.push_back("-F"); + formatCmds.push_back("-t"); + formatCmds.push_back(fsType); + formatCmds.push_back("-b"); + formatCmds.push_back(std::to_string(DEFAULT_BLOCK_SIZE)); + formatCmds.push_back(partPath_); + } else if (fsType == "f2fs") { + formatCmds.push_back(it->second); + formatCmds.push_back(partPath_); + } + return 0; +} + +bool Partition::IsOnlyErase() const +{ + std::vector rawPartName = { + "boot", "fastboot", "kernel", "misc", "system" + }; + auto it = std::find (rawPartName.begin(), rawPartName.end(), partName_); + return it != rawPartName.end(); +} + +uint32_t Partition::GetMountFlags(const std::string &mountFlagsStr, std::string &data) const +{ + static std::map mntInfo = { + { "ro", MS_RDONLY }, + { "rw", 0 }, + { ",sync", MS_SYNCHRONOUS }, + { ",dirsync", MS_DIRSYNC }, + { ",mand", MS_MANDLOCK }, + { ",lazytime", MS_LAZYTIME }, + { ",nosuid", MS_NOSUID }, + { ",nodev", MS_NODEV }, + { ",noexec", MS_NOEXEC }, + { ",noatime", MS_NOATIME }, + { ",nodiratime", MS_NODIRATIME }, + { ",relatime", MS_RELATIME }, + { ",remount", MS_REMOUNT }, + { ",bind", MS_BIND }, + { ",rec", MS_REC }, + { ",unbindable", MS_UNBINDABLE }, + { ",private", MS_PRIVATE }, + { ",slave", MS_SLAVE }, + { ",shared", MS_SHARED }, + { ",defaults", 0 }, + }; + + // get rw flags + uint32_t flags = 0; + std::string::size_type found = std::string::npos; + std::string::size_type start = 0; + while (true) { + found = mountFlagsStr.find_first_of(",", start + 1); + std::string option = mountFlagsStr.substr(start, found - start); + auto iter = mntInfo.find(option); + if (iter != mntInfo.end()) { + flags |= iter->second; + } else { + data.append(option); + data.append(","); + } + if (found == std::string::npos) { + break; + } + start = found; + } + data.pop_back(); // Remove last ',' + return flags; +} +} diff --git a/services/flashd/partition.h b/services/flashd/partition.h new file mode 100755 index 00000000..411568f0 --- /dev/null +++ b/services/flashd/partition.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef FLASHING_PARTITION_H +#define FLASHING_PARTITION_H +#include +#include +#include +#include +#include +#include "blockdevice.h" +#include "flash_utils.h" + +namespace flashd { +enum class PartitionType { + NORMAL, + LOGICAL, + EXTENDED, +}; + +class Partition { +public: + Partition(const std::string &name, const std::string &path, BlockDevicePtr device, FlashingPtr flash) + : partPath_(path), devName_(name), device_(device), flash_(flash) {} + ~Partition(); + + int Load(); + int DoFlash(const std::string &fileName); + int DoFormat(const std::string &fsType); + int DoErase(); + int DoResize(uint32_t blocks); + + bool IsOnlyErase() const; + const std::string GetPartitionName() const; + PartitionType GetPartitionType() const + { + return type_; + } + const std::string GetPartitionPath() const + { + return partPath_; + } +private: + std::string ReadPartitionSysInfo(const std::string &partition, + const std::string &type, std::vector &table); + int Open(); + int WriteRowData(int inputFd, size_t fileSize, std::vector &buffer, size_t dataSize); + int IsBlockDevice(int fd) const; + int GetMountInfo(); + int DoUmount(); + int DoMount(); + int BuildCommandParam(const std::string &fsType, std::vector &formatCmds) const; + uint64_t GetBlockDeviceSize(int fd) const; + uint32_t GetMountFlags(const std::string &mountFlagsStr, std::string &data) const; + + int fd_ = -1; + int partNumber_ { 0 }; // Partition number. + std::string partPath_ {}; + std::string devName_ {}; // partition DEVNAME + std::string partName_ {}; // partition PARTN + PartitionType type_ { PartitionType::NORMAL }; + std::string fsType_ {}; // File system type, ext4, f2fs etc. + std::string mountFlags_ {}; // flags:rw,relatime,fmask=0077,dmask=0077 + std::string mountPoint_ {}; + BlockDevicePtr device_ = nullptr; + FlashingPtr flash_ = nullptr; +}; +using PartitionPtr = Partition *; +} +#endif // FLASHING_PARTITION_H \ No newline at end of file diff --git a/services/fs_manager/BUILD.gn b/services/fs_manager/BUILD.gn index 3ce65a7c..93aad545 100644 --- a/services/fs_manager/BUILD.gn +++ b/services/fs_manager/BUILD.gn @@ -17,7 +17,6 @@ ohos_static_library("libfsmanager") { sources = [ "cmp_partition.cpp", "do_partition.cpp", - "fstab.cpp", "mount.cpp", "partitions.cpp", ] @@ -27,9 +26,11 @@ ohos_static_library("libfsmanager") { "//base/update/updater/interfaces/kits/include", "//base/update/updater/utils/include", "//third_party/bounds_checking_function/include", + "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ + "//base/startup/init_lite/interfaces/innerkits/fs_manager:libfsmanager_static", "//base/update/updater/utils:libutils", "//third_party/bounds_checking_function:libsec_static", ] diff --git a/services/fs_manager/fstab.cpp b/services/fs_manager/fstab.cpp deleted file mode 100644 index 2851568b..00000000 --- a/services/fs_manager/fstab.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * 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 "fs_manager/fstab.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "fs_manager/fstab_api.h" -#include "log/log.h" -#include "utils.h" - -namespace updater { -using utils::SplitString; - -static std::map g_fsManagerMap = { - {"check", FS_MANAGER_CHECK}, - {"wait", FS_MANAGER_WAIT}, -}; - -void ParseFstabPerLine(std::string &line, Fstab &fstab, bool &parseError) -{ - const std::string separator = " \t"; - char *restPtr = nullptr; - struct FstabItem item; - char *p = nullptr; - do { - if ((p = strtok_r(const_cast(line.c_str()), separator.c_str(), &restPtr)) == nullptr) { - fprintf(stderr, "Failed to parse block device.\n"); - break; - } - - item.deviceName = p; - if ((p = strtok_r(nullptr, separator.c_str(), &restPtr)) == nullptr) { - fprintf(stderr, "Failed to parse mount point.\n"); - break; - } - - item.mountPoint = p; - if ((p = strtok_r(nullptr, separator.c_str(), &restPtr)) == nullptr) { - fprintf(stderr, "Failed to parse fs type.\n"); - break; - } - item.fsType = p; - - if ((p = strtok_r(nullptr, separator.c_str(), &restPtr)) == nullptr) { - fprintf(stderr, "Failed to parse mount options.\n"); - break; - } - item.mountOptions = p; - - if ((p = strtok_r(nullptr, separator.c_str(), &restPtr)) == nullptr) { - fprintf(stderr, "Failed to parse fs manager flags.\n"); - break; - } - item.fsManagerFlags = 0; - std::string fsFlags = p; - for (const auto& flag : g_fsManagerMap) { - if (fsFlags.find(flag.first) != std::string::npos) { - item.fsManagerFlags |= flag.second; - } - } - - fstab.emplace_back(std::move(item)); - parseError = false; - } while (0); - - return; -} - -bool ReadFstabFromFile(const std::string &fstabFile, Fstab &fstab) -{ - char *line = nullptr; - size_t allocLen = 0; - ssize_t readLen = 0; - std::string tmpStr = ""; - Fstab tmpTab; - char *realPath = realpath(fstabFile.c_str(), NULL); - if (realPath == nullptr) { - return false; - } - auto fp = std::unique_ptr(fopen(realPath, "r"), fclose); - if (fp.get() == nullptr) { - LOG(ERROR) << "fp is nullptr"; - free(realPath); - return false; - } - free(realPath); - while ((readLen = getline(&line, &allocLen, fp.get())) != -1) { - char *p = nullptr; - if (line[readLen - 1] == '\n') { - line[readLen - 1] = '\0'; - } - p = line; - while (isspace(*p)) { - p++; - } - - if (*p == '\0' || *p == '#') { - continue; - } - - bool parseError = true; - tmpStr = p; - ParseFstabPerLine(tmpStr, tmpTab, parseError); - tmpStr.clear(); - if (parseError) { - free(line); - return false; - } - } - - free(line); - fstab = std::move(tmpTab); - return true; -} - -struct FstabItem* FindFstabItemForMountPoint(Fstab &fstab, const std::string& mp) -{ - for (auto &item : fstab) { - if (item.mountPoint == mp) { - return &item; - } - } - return nullptr; -} - -struct FstabItem* FindFstabItemForPath(Fstab &fstab, const std::string &path) -{ - struct FstabItem *item = nullptr; - std::string tmp(path); - if (path.empty()) { - return nullptr; - } - while (true) { - item = FindFstabItemForMountPoint(fstab, tmp); - if (item != nullptr) { - return item; - } - auto sep = tmp.find_last_of('/'); - if (sep == std::string::npos) { - return nullptr; - } - if (sep == 0) { - tmp = "/"; - break; - } - tmp = tmp.substr(0, sep); - } - return nullptr; -} - -static bool ParseDefaultMountFlags(const std::string &mountFlag, unsigned long &flags) -{ - std::map mountFlags = { - { "noatime", MS_NOATIME }, - { "noexec", MS_NOEXEC }, - { "nosuid", MS_NOSUID }, - { "nodev", MS_NODEV }, - { "nodiratime", MS_NODIRATIME }, - { "ro", MS_RDONLY }, - { "rw", 0 }, - { "sync", MS_SYNCHRONOUS }, - { "remount", MS_REMOUNT }, - { "bind", MS_BIND }, - { "rec", MS_REC }, - { "unbindable", MS_UNBINDABLE }, - { "private", MS_PRIVATE }, - { "slave", MS_SLAVE }, - { "shared", MS_SHARED }, - { "defaults", 0 }, - }; - for (const auto &flag : mountFlags) { - if (mountFlag == flag.first) { - flags = flag.second; - return true; - } - } - return false; -} - -unsigned long GetMountFlags(const std::string &mountOptions, std::string &fsSpecificOptions) -{ - unsigned long flags = 0; - unsigned long tmpFlag = 0; - - auto options = SplitString(mountOptions, ","); - fsSpecificOptions.clear(); - for (const auto &option : options) { - if (ParseDefaultMountFlags(option, tmpFlag)) { - flags |= tmpFlag; - } else { // not default mount flags, maybe File system specific. - fsSpecificOptions.append(option); - fsSpecificOptions.append(","); - } - } - fsSpecificOptions.pop_back(); // Remove last ',' - LOG(DEBUG) << "File system specific mount options is " << fsSpecificOptions; - return flags; -} -} // updater diff --git a/services/fs_manager/mount.cpp b/services/fs_manager/mount.cpp index 2b33668d..0a71611f 100644 --- a/services/fs_manager/mount.cpp +++ b/services/fs_manager/mount.cpp @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "fs_manager/mount.h" +#include "fs_manager/mount.h" #include #include #include @@ -22,166 +22,34 @@ #include #include #include -#include "fs_manager/fstab.h" -#include "fs_manager/fstab_api.h" #include "log/log.h" #include "utils.h" namespace updater { using updater::utils::SplitString; static std::string g_defaultUpdaterFstab = ""; -static Fstab g_fstab; - -static bool IsSupportedFilesystem(const std::string &fsType) -{ - std::vector supportedFilesystems = {"ext4", "f2fs", "vfat"}; - - bool supported = false; - for (const auto &fs : supportedFilesystems) { - if (fsType == fs) { - supported = true; - break; - } - } - return supported; -} - -static int ExecCommand(std::vector cmds) -{ - std::vector extractedCmds; - - for (const auto &cmd : cmds) { - extractedCmds.push_back(const_cast(cmd.c_str())); - } - extractedCmds.push_back(nullptr); - pid_t pid = fork(); - if (pid < 0) { - LOG(ERROR) << "Fork new process to format failed: " << errno; - ERROR_CODE(CODE_FORK_FAIL); - return -1; - } - if (pid == 0) { - execv(extractedCmds[0], extractedCmds.data()); - exit(-1); - } - int status; - waitpid(pid, &status, 0); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - LOG(ERROR) << "Command " << extractedCmds[0] << " failed with status " << WEXITSTATUS(status); - } - return WEXITSTATUS(status); -} - -static int DoFormat(const std::string &devPath, const std::string &fsType) -{ - std::map fsToolsMap = { - { "ext4", "/bin/mke2fs" }, - { "f2fs", "/bin/make_f2fs" }, - }; - int ret = 0; - auto it = fsToolsMap.find(fsType); - if (it == fsToolsMap.end()) { - LOG(ERROR) << "Can not find fs tools for " << fsType; - return -1; - } - auto fsTool = it->second; - if (fsType == "ext4") { - constexpr int blockSize = 4096; - std::vector formatCmds; - formatCmds.push_back(fsTool); - formatCmds.push_back("-F"); - formatCmds.push_back("-t"); - formatCmds.push_back(fsType); - formatCmds.push_back("-b"); - formatCmds.push_back(std::to_string(blockSize)); - formatCmds.push_back(devPath); - ret = ExecCommand(formatCmds); - } else if (fsType == "f2fs") { - std::vector formatCmds; - formatCmds.push_back(fsTool); - formatCmds.push_back(devPath); - ret = ExecCommand(formatCmds); - } - return ret; -} - -int FormatPartition(const std::string &path) -{ - struct FstabItem *item = FindFstabItemForPath(g_fstab, path); - if (item == nullptr) { - LOG(ERROR) << "Cannot find fstab item for " << path << " to format."; - return -1; - } - - if (item->mountPoint == "/") { - /* Can not format root */ - return 0; - } - - if (!IsSupportedFilesystem(item->fsType)) { - LOG(ERROR) << "Try to format " << item->mountPoint << " with unsupported file system type: " << item->fsType; - return -1; - } - - // Umount first - if (UmountForPath(path) != 0) { - return -1; - } - int ret = DoFormat(item->deviceName, item->fsType); - if (ret != 0) { - LOG(ERROR) << "Format " << path << " failed"; - } - return ((ret != 0) ? -1 : 0); -} - -static MountStatus GetMountStatusForMountPoint(const std::string &mountPoint) +static Fstab *g_fstab; +static std::string GetFstabFile() { - char buffer[512]; - size_t n; - constexpr size_t numMountItems = 6; - const std::string mountFile = "/proc/mounts"; - auto fp = std::unique_ptr(fopen(mountFile.c_str(), "r"), fclose); - - while (fgets(buffer, sizeof(buffer) - 1, fp.get()) != nullptr) { - n = strlen(buffer); - if (n > 0 && buffer[n - 1] == '\n') { - buffer[n - 1] = '\0'; - } - std::string line(buffer); - std::vector mountItems = SplitString(line); - if (mountItems.size() == numMountItems) { - // Second item in /proc/mounts is mount point - if (mountItems[1] == mountPoint) { - return MountStatus::MOUNT_MOUNTED; - } + /* check vendor fstab files from specific directory */ + std::vector specificFstabFiles = {"/vendor/etc/fstab.updater"}; + for (auto& fstabFile : specificFstabFiles) { + if (access(fstabFile.c_str(), F_OK) == 0) { + return fstabFile; } } - - // Cannot find it from system. - return MountStatus::MOUNT_UMOUNTED; + return ""; } MountStatus GetMountStatusForPath(const std::string &path) { - struct FstabItem *item = FindFstabItemForPath(g_fstab, path); + FstabItem *item = FindFstabItemForPath(*g_fstab, path.c_str()); if (item == nullptr) { return MountStatus::MOUNT_ERROR; } return GetMountStatusForMountPoint(item->mountPoint); } -static std::string GetFstabFile() -{ - /* check vendor fstab files from specific directory */ - std::vector specificFstabFiles = {"/vendor/etc/fstab.updater", "/odm/etc/fstab.updater"}; - for (auto& fstabFile : specificFstabFiles) { - if (access(fstabFile.c_str(), F_OK) == 0) { - return fstabFile; - } - } - return ""; -} - void LoadFstab() { std::string fstabFile = g_defaultUpdaterFstab; @@ -192,22 +60,20 @@ void LoadFstab() } } // Clear fstab before read fstab file. - g_fstab.clear(); - if (ReadFstabFromFile(fstabFile, g_fstab) == false) { + if ((g_fstab = ReadFstabFromFile(fstabFile.c_str(), false)) == nullptr) { LOG(WARNING) << "Read " << fstabFile << " failed"; return; } LOG(DEBUG) << "Updater filesystem config info:"; - for (const auto &item : g_fstab) { - LOG(DEBUG) << "\tDevice: " << item.deviceName; - LOG(DEBUG) << "\tMount point : " << item.mountPoint; - LOG(DEBUG) << "\tFs type : " << item.fsType; - LOG(DEBUG) << "\tMount options: " << item.mountOptions; + for (FstabItem *item = g_fstab->head; item != nullptr; item = item->next) { + LOG(DEBUG) << "\tDevice: " << item->deviceName; + LOG(DEBUG) << "\tMount point : " << item->mountPoint; + LOG(DEBUG) << "\tFs type : " << item->fsType; + LOG(DEBUG) << "\tMount options: " << item->mountOptions; } } - void LoadSpecificFstab(const std::string &fstabName) { g_defaultUpdaterFstab = fstabName; @@ -217,21 +83,20 @@ void LoadSpecificFstab(const std::string &fstabName) int UmountForPath(const std::string& path) { - struct FstabItem *item = FindFstabItemForPath(g_fstab, path); - MountStatus rc; + FstabItem *item = FindFstabItemForPath(*g_fstab, path.c_str()); if (item == nullptr) { LOG(ERROR) << "Cannot find fstab item for " << path << " to umount."; return -1; } LOG(DEBUG) << "Umount for path " << path; - rc = GetMountStatusForMountPoint(item->mountPoint); - if (rc == MountStatus::MOUNT_ERROR) { + MountStatus rc = GetMountStatusForMountPoint(item->mountPoint); + if (rc == MOUNT_ERROR) { return -1; - } else if (rc == MountStatus::MOUNT_UMOUNTED) { + } else if (rc == MOUNT_UMOUNTED) { return 0; } else { - int ret = umount(item->mountPoint.c_str()); + int ret = umount(item->mountPoint); if (ret == -1) { LOG(ERROR) << "Umount " << item->mountPoint << "failed: " << errno; return -1; @@ -240,54 +105,10 @@ int UmountForPath(const std::string& path) return 0; } -static int Mount(const std::string &source, const std::string &target, const std::string &fsType, - unsigned long flags, const std::string &data) -{ - struct stat st {}; - int rc; - if (stat(target.c_str(), &st) != 0 && errno != ENOENT) { - LOG(ERROR) << "Cannot get " << target << " status: " << errno; - return -1; - } - if ((st.st_mode & S_IFMT) == S_IFLNK) { // link, delete it. - unlink(target.c_str()); - } - mkdir(target.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - errno = 0; - while ((rc = mount(source.c_str(), target.c_str(), fsType.c_str(), flags, data.c_str()) != 0)) { - if (errno == EAGAIN) { - LOG(INFO) << "Mount " << source << " to " << target << " failed. try again"; - continue; - } else { - break; - } - } - return rc; -} - -static int DoMount(const struct FstabItem &item) -{ - unsigned long mountFlags; - std::string fsSpecificOptions; - - mountFlags = GetMountFlags(item.mountOptions, fsSpecificOptions); - if (!IsSupportedFilesystem(item.fsType)) { - LOG(ERROR) << "Unsupported file system \"" << item.fsType << "\""; - return -1; - } - int rc = Mount(item.deviceName, item.mountPoint, item.fsType, mountFlags, fsSpecificOptions); - if (rc != 0) { - LOG(ERROR) << "Mount " << item.deviceName << " to " << item.mountPoint << " failed: " << errno; - } else { - LOG(INFO) << "Mount " << item.deviceName << " to " << item.mountPoint << " successful"; - } - return rc; -} - int MountForPath(const std::string &path) { - struct FstabItem *item = FindFstabItemForPath(g_fstab, path); - int ret; + FstabItem *item = FindFstabItemForPath(*g_fstab, path.c_str()); + int ret = -1; if (item == nullptr) { LOG(ERROR) << "Cannot find fstab item for " << path << " to mount."; return -1; @@ -296,51 +117,68 @@ int MountForPath(const std::string &path) LOG(DEBUG) << "Mount for path " << path; MountStatus rc = GetMountStatusForMountPoint(item->mountPoint); if (rc == MountStatus::MOUNT_ERROR) { - return -1; + ret = -1; } else if (rc == MountStatus::MOUNT_MOUNTED) { - std::cout << path << " already mounted\n"; - return 0; + LOG(INFO) << path << " already mounted"; + ret = 0; } else { - ret = DoMount(*item); + ret = MountOneItem(item); } return ret; } -struct FstabItem *GetItemForMountPoint(const std::string &mountPoint) +int FormatPartition(const std::string &path) { - if (g_fstab.empty()) { - LOG(ERROR) << "Fstab is empty."; - return nullptr; + FstabItem *item = FindFstabItemForPath(*g_fstab, path.c_str()); + if (item == nullptr) { + LOG(ERROR) << "Cannot find fstab item for " << path << " to format."; + return -1; } - for (auto& item : g_fstab) { - if (item.mountPoint == mountPoint) { - return &item; - } + + if (strcmp(item->mountPoint, "/") == 0) { + /* Can not format root */ + return 0; } - return nullptr; + + if (!IsSupportedFilesystem(item->fsType)) { + LOG(ERROR) << "Try to format " << item->mountPoint << " with unsupported file system type: " << item->fsType; + return -1; + } + + // Umount first + if (UmountForPath(path) != 0) { + return -1; + } + int ret = DoFormat(item->deviceName, item->fsType); + if (ret != 0) { + LOG(ERROR) << "Format " << path << " failed"; + } + return ((ret != 0) ? -1 : 0); } int SetupPartitions() { - if (g_fstab.empty()) { - LOG(ERROR) << "Fstab is empty."; + if (g_fstab == NULL || g_fstab->head == NULL) { + LOG(ERROR) << "Fstab is invalid"; return -1; } - for (const auto &item : g_fstab) { - if (item.mountPoint == "/" || item.mountPoint == "/tmp" || item.fsType == "none" || - item.mountPoint == "/sdcard") { + for (const FstabItem *item = g_fstab->head; item != nullptr; item = item->next) { + std::string mountPoint(item->mountPoint); + std::string fsType(item->fsType); + if (mountPoint == "/" || mountPoint == "/tmp" || fsType == "none" || + mountPoint == "/sdcard") { continue; } - if (item.mountPoint == "/data") { - if (MountForPath(item.mountPoint) != 0) { - LOG(ERROR) << "Expected partition " << item.mountPoint << " is not mounted."; + if (mountPoint == "/data") { + if (MountForPath(mountPoint) != 0) { + LOG(ERROR) << "Expected partition " << mountPoint << " is not mounted."; return -1; } continue; } - if (UmountForPath(item.mountPoint) != 0) { - LOG(ERROR) << "Umount " << item.mountPoint << " failed"; + if (UmountForPath(mountPoint) != 0) { + LOG(ERROR) << "Umount " << mountPoint << " failed"; return -1; } } @@ -351,12 +189,11 @@ const std::string GetBlockDeviceByMountPoint(const std::string &mountPoint) { std::string blockDevice = ""; if (!mountPoint.empty()) { - auto item = FindFstabItemForMountPoint(g_fstab, mountPoint); - if (item) { + FstabItem *item = FindFstabItemForMountPoint(*g_fstab, mountPoint.c_str()); + if (item != NULL) { blockDevice = item->deviceName; } } return blockDevice; } } // updater - diff --git a/services/include/applypatch/partition_record.h b/services/include/applypatch/partition_record.h index d3418992..962d43f4 100644 --- a/services/include/applypatch/partition_record.h +++ b/services/include/applypatch/partition_record.h @@ -68,7 +68,7 @@ private: private: std::string GetMiscPartitionPath(const std::string &mountPoint = "/misc"); - PartitionRecordInfo info_; + PartitionRecordInfo info_ {}; // offset of partition record in misc. // offset is not start from zero, but // start from the global offset of misc partition. diff --git a/services/include/applypatch/transfer_manager.h b/services/include/applypatch/transfer_manager.h index 3231917f..b2e06bdb 100644 --- a/services/include/applypatch/transfer_manager.h +++ b/services/include/applypatch/transfer_manager.h @@ -73,6 +73,7 @@ public: } std::string ReloadForRetry() const; bool CheckResult(const CommandResult result, const std::string &cmd, const CommandType &type); + bool NeedSetProgress(const CommandType &type); private: bool RegisterForRetry(const std::string &cmd); diff --git a/services/include/applypatch/updater_env.h b/services/include/applypatch/updater_env.h index 4ce1b8f7..121e1a4d 100644 --- a/services/include/applypatch/updater_env.h +++ b/services/include/applypatch/updater_env.h @@ -22,6 +22,7 @@ #include "package/pkg_manager.h" #include "script_instruction.h" #include "script_manager.h" +#include "updater/updater.h" using uscript::UScriptEnv; using uscript::UScriptInstructionFactory; @@ -30,8 +31,8 @@ using uscript::UScriptInstructionFactoryPtr; namespace updater { class UpdaterEnv : public UScriptEnv { public: - UpdaterEnv(hpackage::PkgManager::PkgManagerPtr pkgManager, FILE* pipeWrite, bool retry) : - UScriptEnv(pkgManager), pipeWrite_(pipeWrite), isRetry_(retry) {} + UpdaterEnv(hpackage::PkgManager::PkgManagerPtr pkgManager, PostMessageFunction postMessage, bool retry) + : UScriptEnv(pkgManager), postMessage_(postMessage), isRetry_(retry) {} virtual ~UpdaterEnv(); virtual void PostMessage(const std::string &cmd, std::string content); @@ -43,7 +44,7 @@ public: } private: UScriptInstructionFactoryPtr factory_ = nullptr; - FILE* pipeWrite_ = nullptr; + PostMessageFunction postMessage_ = nullptr; bool isRetry_ = false; }; } diff --git a/services/include/flashd/flashd.h b/services/include/flashd/flashd.h new file mode 100755 index 00000000..8eae9598 --- /dev/null +++ b/services/include/flashd/flashd.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UPDATER_FLASHING_H +#define UPDATER_FLASHING_H +#include +#include + +namespace flashd { +enum { + FLASHING_SYSTEM_ERROR = 100, + FLASHING_ARG_INVALID, + FLASHING_IMAGE_INVALID, + FLASHING_PART_NOEXIST, + FLASHING_NOPERMISSION, + FLASHING_PART_WRITE_ERROR, + FLASHING_PACKAGE_INVALID, + FLASHING_SPACE_NOTENOUGH, + FLASHING_INVALID_SPACE, + FLASHING_FSTYPE_NOT_SUPPORT, +}; + +enum UpdateModType { + UPDATEMOD_UPDATE, + UPDATEMOD_FLASH, + UPDATEMOD_ERASE, + UPDATEMOD_FORMAT, + UPDATEMOD_MAX +}; + +static constexpr uint16_t MAX_SIZE_BUF = 1024; +static constexpr uint32_t PERCENT_FINISH = 100; +static constexpr uint32_t PERCENT_CLEAR = (uint32_t)-1; + +#ifndef LOCAL_SUPPORT +const std::string FORMAT_TOOL_FOR_EXT4 = "/bin/mke2fs"; +const std::string FORMAT_TOOL_FOR_F2FS = "/bin/make_f2fs"; +const std::string RESIZE_TOOL = "/bin/resize2fs"; +const std::string FLASHD_FILE_PATH = "/data/updater/"; +const std::string FLASHD_HDC_LOG_PATH = "/tmp/flashd_hdc.log"; +#else +const std::string FORMAT_TOOL_FOR_EXT4 = "/usr/sbin/mke2fs"; +const std::string FORMAT_TOOL_FOR_F2FS = "/system/bin/make_f2fs"; +const std::string RESIZE_TOOL = "/bin/resize2fs"; +const std::string FLASHD_FILE_PATH = "/home/axw/develop/build/"; +const std::string FLASHD_HDC_LOG_PATH = "/home/axw/develop/build/hdc.log"; +#endif +static constexpr uint32_t MIN_BLOCKS_FOR_UPDATE = 1024 * 1024; +static constexpr uint32_t DEFAULT_BLOCK_SIZE = 4096; +static constexpr uint32_t DEFAULT_SIZE_UNIT = 1024 * 1024; + +using FlashHandle = void *; +int flashd_main(int argc, char **argv); +using ProgressFunction = std::function; + +int CreateFlashInstance(FlashHandle *handle, std::string &errorMsg, ProgressFunction progressor); +int DoUpdaterPrepare(FlashHandle handle, uint8_t type, const std::string &cmdParam, std::string &filePath); +int DoUpdaterFlash(FlashHandle handle, uint8_t type, const std::string &cmdParam, const std::string &filePath); +int DoUpdaterFinish(FlashHandle handle, uint8_t type, const std::string &partition); +} // namespace flashd +#endif /* UPDATER_FLASHING_H */ diff --git a/services/include/fs_manager/fstab_api.h b/services/include/fs_manager/fstab_api.h deleted file mode 100644 index a8e36a25..00000000 --- a/services/include/fs_manager/fstab_api.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * 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. - */ - -#ifndef __UPDATER_FS_MANAGER_FSTAB_API_H -#define __UPDATER_FS_MANAGER_FSTAB_API_H -#include -#include "fs_manager/fstab.h" - -namespace updater { -bool ReadFstabFromFile(const std::string &fstabFile, Fstab &fstabs); -struct FstabItem* FindFstabItemForPath(Fstab &fstab, const std::string &path); -struct FstabItem* FindFstabItemForMountPoint(Fstab &fstab, const std::string &mp); -unsigned long GetMountFlags(const std::string &mountOptions, std::string &fsSpecificOptions); -} // updater -#endif // __UPDATER_FS_MANAGER_FSTAB_API_ - diff --git a/services/include/fs_manager/mount.h b/services/include/fs_manager/mount.h index 7d70ccbb..744a8d13 100644 --- a/services/include/fs_manager/mount.h +++ b/services/include/fs_manager/mount.h @@ -16,24 +16,16 @@ #define UPDATER_FS_MANAGER_MOUNT_H #include -#include "fs_manager/fstab_api.h" -#include "fs_manager/fstab.h" +#include "fs_manager/fs_manager.h" namespace updater { -enum MountStatus : int { - MOUNT_ERROR = -1, - MOUNT_UMOUNTED = 0, - MOUNT_MOUNTED = 1, -}; - void LoadFstab(); /* Load fstab */ void LoadSpecificFstab(const std::string &fstabName); int FormatPartition(const std::string &path); int UmountForPath(const std::string &path); int MountForPath(const std::string &path); -MountStatus GetMountStatusForPath(const std::string &path); -struct FstabItem *GetItemForMountPoint(const std::string &mountPoint); int SetupPartitions(); const std::string GetBlockDeviceByMountPoint(const std::string &mountPoint); +MountStatus GetMountStatusForPath(const std::string &path); } // updater #endif // UPDATER_FS_MANAGER_MOUNT_H \ No newline at end of file diff --git a/services/include/package/pkg_manager.h b/services/include/package/pkg_manager.h index 9cf37201..e70c9d8d 100644 --- a/services/include/package/pkg_manager.h +++ b/services/include/package/pkg_manager.h @@ -47,6 +47,13 @@ enum { PKG_VERIFY_FAIL, }; +enum { + POST_TYPE_UPLOAD_PKG = 0, + POST_TYPE_DECODE_PKG, + POST_TYPE_VERIFY_PKG, + POST_TYPE_WRITE_PARTITION +}; + /** * Package information */ @@ -203,6 +210,8 @@ public: } }; +using PkgDecodeProgress = std::function; + /** * Get a singleton PkgManager instance. */ @@ -334,6 +343,10 @@ public: std::vector &fileIds) = 0; virtual int32_t ParsePackage(StreamPtr stream, std::vector &fileIds, int32_t type) = 0; + + virtual void SetPkgDecodeProgress(PkgDecodeProgress decodeProgress) = 0; + + virtual void PostDecodeProgress(int type, size_t writeDataLen, const void *context) = 0; }; } // namespace hpackage #endif // PKG_MANAGER_H diff --git a/services/include/updater/updater.h b/services/include/updater/updater.h index e71b1b9c..0d94c5ab 100644 --- a/services/include/updater/updater.h +++ b/services/include/updater/updater.h @@ -26,9 +26,12 @@ enum UpdaterStatus { UPDATE_CORRUPT, /* package or verify failed, something is broken. */ UPDATE_SKIP, /* skip update because of condition is not satisfied, e.g, battery is low */ UPDATE_RETRY, + UPDATE_SPACE_NOTENOUGH, UPDATE_UNKNOWN }; +using PostMessageFunction = std::function; + UpdaterStatus DoInstallUpdaterPackage(hpackage::PkgManager::PkgManagerPtr pkgManager, const std::string &packagePath, int retryCount); @@ -38,5 +41,19 @@ UpdaterStatus StartUpdaterProc(hpackage::PkgManager::PkgManagerPtr pkgManager, c int GetUpdatePackageInfo(hpackage::PkgManager::PkgManagerPtr pkgManager, const std::string& path); int UpdatePreProcess(hpackage::PkgManager::PkgManagerPtr pkgManager, const std::string& path); + +int ExecUpdate(hpackage::PkgManager::PkgManagerPtr pkgManager, int retry, PostMessageFunction postMessage); + +bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog); + +void CompressLogs(const std::string &name); + +int IsSpaceCapacitySufficient(const std::string &packagePath); + +bool IsSDCardExist(const std::string &sdcard_path); + +void PostUpdater(); + +std::vector ParseParams(int argc, char **argv); } // updater #endif /* UPDATER_UPDATER_H */ diff --git a/services/include/updater/updater_const.h b/services/include/updater/updater_const.h index 7dad0359..88775927 100644 --- a/services/include/updater/updater_const.h +++ b/services/include/updater/updater_const.h @@ -27,6 +27,8 @@ const std::string UPDATER_PATH = "/data/updater"; const std::string MISC_FILE = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/misc"; const std::string UPDATER_BINARY = "updater_binary"; const std::string SDCARD_PATH = "/sdcard"; +const std::string UPDATER_HDC_LOG = "/data/updater/log/flashd_hdc.log"; + #ifndef UPDATER_UT const std::string SDCARD_CARD_PATH = "/sdcard/updater"; const std::string SDCARD_CARD_PKG_PATH = "/sdcard/updater/updater.zip"; diff --git a/services/main.cpp b/services/main.cpp index 322f128c..e0173eef 100644 --- a/services/main.cpp +++ b/services/main.cpp @@ -12,10 +12,42 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include "flashd/flashd.h" +#include "fs_manager/mount.h" +#include "log/log.h" +#include "misc_info/misc_info.h" +#include "updater/updater_const.h" #include "updater_main.h" +using namespace updater; + int main(int argc, char **argv) { + struct UpdateMessage boot {}; + // read from misc + bool ret = ReadUpdaterMessage(MISC_FILE, boot); + if (!ret) { + printf("ReadUpdaterMessage MISC_FILE failed!\n"); + } + // if boot.update is empty, read from command.The Misc partition may have dirty data, + // so strlen(boot.update) is not used, which can cause system exceptions. + if (boot.update[0] == '\0' && !access(COMMAND_FILE.c_str(), 0)) { + ret = ReadUpdaterMessage(COMMAND_FILE, boot); + if (!ret) { + printf("ReadUpdaterMessage COMMAND_FILE failed!\n"); + } + } + + const int flashBootLength = 10; + bool useFlash = memcmp(boot.command, "boot_flash", flashBootLength) == 0; + InitUpdaterLogger(useFlash ? "FLASHD" : "UPDATER", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); + SetLogLevel(VERBOSE); + LoadFstab(); + STAGE(UPDATE_STAGE_OUT) << "Init Params: " << boot.update; + LOG(INFO) << "boot.command " << boot.command; + LOG(INFO) << "boot.update " << boot.update; + if (useFlash) { + return flashd::flashd_main(argc, argv); + } return updater::UpdaterMain(argc, argv); } diff --git a/services/package/pkg_manager/pkg_managerImpl.cpp b/services/package/pkg_manager/pkg_managerImpl.cpp index 8dbff31c..684536c0 100644 --- a/services/package/pkg_manager/pkg_managerImpl.cpp +++ b/services/package/pkg_manager/pkg_managerImpl.cpp @@ -52,7 +52,9 @@ PkgManager::PkgManagerPtr PkgManager::GetPackageInstance() PkgManager::PkgManagerPtr PkgManager::CreatePackageInstance() { - return new PkgManagerImpl(); + PkgManager::PkgManagerPtr impl = new PkgManagerImpl(); + PKG_LOGI("CreatePackageInstance %p", impl); + return impl; } void PkgManager::ReleasePackageInstance(PkgManager::PkgManagerPtr manager) @@ -60,6 +62,7 @@ void PkgManager::ReleasePackageInstance(PkgManager::PkgManagerPtr manager) if (manager == nullptr) { return; } + PKG_LOGI("ReleasePackageInstance %p", manager); if (g_pkgManagerInstance == manager) { delete g_pkgManagerInstance; g_pkgManagerInstance = nullptr; @@ -205,16 +208,16 @@ PkgFilePtr PkgManagerImpl::CreatePackage(PkgStreamPtr stream, PkgFile::PkgType t PkgFilePtr pkgFile = nullptr; switch (type) { case PkgFile::PKG_TYPE_UPGRADE: - pkgFile = new UpgradePkgFile(stream, header); + pkgFile = new UpgradePkgFile(this, stream, header); break; case PkgFile::PKG_TYPE_ZIP: - pkgFile = new ZipPkgFile(stream); + pkgFile = new ZipPkgFile(this, stream); break; case PkgFile::PKG_TYPE_LZ4: - pkgFile = new Lz4PkgFile(stream); + pkgFile = new Lz4PkgFile(this, stream); break; case PkgFile::PKG_TYPE_GZIP: - pkgFile = new GZipPkgFile(stream); + pkgFile = new GZipPkgFile(this, stream); break; default: return nullptr; @@ -396,7 +399,7 @@ int32_t PkgManagerImpl::CreatePkgStream(StreamPtr &stream, const std::string &fi int32_t PkgManagerImpl::CreatePkgStream(StreamPtr &stream, const std::string &fileName, const PkgBuffer &buffer) { - PkgStreamPtr pkgStream = new MemoryMapStream(fileName, buffer, PkgStream::PkgStreamType_Buffer); + PkgStreamPtr pkgStream = new MemoryMapStream(this, fileName, buffer, PkgStream::PkgStreamType_Buffer); PKG_CHECK(pkgStream != nullptr, return -1, "Failed to create stream"); stream = pkgStream; return PKG_SUCCESS; @@ -438,7 +441,7 @@ int32_t PkgManagerImpl::CreatePkgStream(PkgStreamPtr &stream, const std::string FILE *file = nullptr; file = fopen(fileName.c_str(), modeFlags[type]); PKG_CHECK(file != nullptr, return PKG_INVALID_FILE, "Fail to open file %s ", fileName.c_str()); - stream = new FileStream(fileName, file, type); + stream = new FileStream(this, fileName, file, type); } else if (type == PkgStream::PkgStreamType_MemoryMap) { size_t fileSize = size; if (fileSize == 0) { @@ -451,7 +454,7 @@ int32_t PkgManagerImpl::CreatePkgStream(PkgStreamPtr &stream, const std::string uint8_t *memoryMap = MapMemory(fileName, fileSize); PKG_CHECK(memoryMap != nullptr, return PKG_INVALID_FILE, "Fail to map memory %s ", fileName.c_str()); PkgBuffer buffer(memoryMap, fileSize); - stream = new MemoryMapStream(fileName, buffer); + stream = new MemoryMapStream(this, fileName, buffer); } else { return -1; } @@ -462,7 +465,7 @@ int32_t PkgManagerImpl::CreatePkgStream(PkgStreamPtr &stream, const std::string int32_t PkgManagerImpl::CreatePkgStream(PkgStreamPtr &stream, const std::string &fileName, PkgStream::ExtractFileProcessor processor, const void *context) { - stream = new ProcessorStream(fileName, processor, context); + stream = new ProcessorStream(this, fileName, processor, context); PKG_CHECK(stream != nullptr, return -1, "Failed to create stream"); return PKG_SUCCESS; } @@ -588,6 +591,7 @@ int32_t PkgManagerImpl::GenerateFileDigest(PkgStreamPtr stream, PKG_IS_TRUE_DONE(flags & DIGEST_FLAGS_HAS_SIGN, algorithm->Update(buff, readLen)); PKG_IS_TRUE_DONE(flags & DIGEST_FLAGS_NO_SIGN, algorithmInner->Update(buff, readLen)); offset += readLen; + PostDecodeProgress(POST_TYPE_VERIFY_PKG, readLen, nullptr); readLen = 0; } @@ -677,8 +681,8 @@ int32_t PkgManagerImpl::DecompressBuffer(FileInfoPtr info, const PkgBuffer &data PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, "Can not get algorithm for %s", info->identity.c_str()); - std::shared_ptr inStream = std::make_shared(info->identity, - data, PkgStream::PkgStreamType_Buffer); + std::shared_ptr inStream = std::make_shared( + (PkgManager::PkgManagerPtr)this, info->identity, data, PkgStream::PkgStreamType_Buffer); PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, "Can not create stream for %s", info->identity.c_str()); PkgAlgorithmContext context = {{0, 0}, {data.length, 0}, 0, info->digestMethod}; int32_t ret = algorithm->Unpack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), context); @@ -698,8 +702,8 @@ int32_t PkgManagerImpl::CompressBuffer(FileInfoPtr info, const PkgBuffer &data, PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(info); PKG_CHECK(algorithm != nullptr, return PKG_INVALID_PARAM, "Can not get algorithm for %s", info->identity.c_str()); - std::shared_ptr inStream = std::make_shared(info->identity, - data, PkgStream::PkgStreamType_Buffer); + std::shared_ptr inStream = std::make_shared( + (PkgManager::PkgManagerPtr)this, info->identity, data, PkgStream::PkgStreamType_Buffer); PKG_CHECK(inStream != nullptr, return PKG_INVALID_PARAM, "Can not create stream for %s", info->identity.c_str()); PkgAlgorithmContext context = {{0, 0}, {0, data.length}, 0, info->digestMethod}; int32_t ret = algorithm->Pack(inStream.get(), PkgStreamImpl::ConvertPkgStream(output), context); @@ -710,4 +714,11 @@ int32_t PkgManagerImpl::CompressBuffer(FileInfoPtr info, const PkgBuffer &data, info->unpackedSize = context.unpackedSize; return PKG_SUCCESS; } + +void PkgManagerImpl::PostDecodeProgress(int type, size_t writeDataLen, const void *context) +{ + if (decodeProgress_ != nullptr) { + decodeProgress_(type, writeDataLen, context); + } +} } // namespace hpackage diff --git a/services/package/pkg_manager/pkg_manager_impl.h b/services/package/pkg_manager/pkg_manager_impl.h index 1233bb43..04dd1039 100644 --- a/services/package/pkg_manager/pkg_manager_impl.h +++ b/services/package/pkg_manager/pkg_manager_impl.h @@ -73,6 +73,13 @@ public: int32_t ParsePackage(StreamPtr stream, std::vector &fileIds, int32_t type) override; int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName, const PkgBuffer &buffer) override; + + void SetPkgDecodeProgress(PkgDecodeProgress decodeProgress) override + { + decodeProgress_ = decodeProgress; + } + + void PostDecodeProgress(int type, size_t writeDataLen, const void *context) override; private: PkgFilePtr CreatePackage(PkgStreamPtr stream, PkgFile::PkgType type, PkgInfoPtr header = nullptr); @@ -111,6 +118,7 @@ private: std::vector pkgFiles_ {}; std::map pkgStreams_ {}; std::string signVerifyKeyName_ {}; + PkgDecodeProgress decodeProgress_ { nullptr }; }; } // namespace hpackage #endif // PKG_MANAGER_IMPL_H diff --git a/services/package/pkg_manager/pkg_stream.cpp b/services/package/pkg_manager/pkg_stream.cpp index 2974d4eb..7f28de2f 100644 --- a/services/package/pkg_manager/pkg_stream.cpp +++ b/services/package/pkg_manager/pkg_stream.cpp @@ -18,6 +18,7 @@ #include #include #include "pkg_manager.h" +#include "pkg_manager_impl.h" #include "pkg_utils.h" #include "securec.h" @@ -47,6 +48,13 @@ bool PkgStreamImpl::IsRef() const return refCount_ == 0; } +void PkgStreamImpl::PostDecodeProgress(int type, size_t writeDataLen, const void *context) +{ + if (pkgManager_ != nullptr) { + pkgManager_->PostDecodeProgress(type, writeDataLen, context); + } +} + FileStream::~FileStream() { if (stream_ != nullptr) { @@ -76,6 +84,7 @@ int32_t FileStream::Write(const PkgBuffer &data, size_t size, size_t offset) fseek(stream_, offset, SEEK_SET); size_t len = fwrite(data.buffer, size, 1, stream_); PKG_CHECK(len == 1, return PKG_INVALID_STREAM, "Write buffer fail"); + PostDecodeProgress(POST_TYPE_DECODE_PKG, size, nullptr); return PKG_SUCCESS; } @@ -143,6 +152,7 @@ int32_t MemoryMapStream::Write(const PkgBuffer &data, size_t size, size_t start) PKG_CHECK(copyLen >= size, return PKG_INVALID_STREAM, "Write fail copyLen %zu, %zu", copyLen, size); int32_t ret = memcpy_s(memMap_ + currOffset_, memSize_ - currOffset_, data.buffer, size); PKG_CHECK(ret == PKG_SUCCESS, return PKG_INVALID_STREAM, "Write fail"); + PostDecodeProgress(POST_TYPE_DECODE_PKG, size, nullptr); return PKG_SUCCESS; } diff --git a/services/package/pkg_manager/pkg_stream.h b/services/package/pkg_manager/pkg_stream.h index 18f06ae7..02d21feb 100644 --- a/services/package/pkg_manager/pkg_stream.h +++ b/services/package/pkg_manager/pkg_stream.h @@ -27,7 +27,8 @@ class PkgStreamImpl; using PkgStreamPtr = PkgStreamImpl *; class PkgStreamImpl : public PkgStream { public: - explicit PkgStreamImpl(std::string fileName) : fileName_(fileName), refCount_(0) {} + explicit PkgStreamImpl(PkgManager::PkgManagerPtr pkgManager, std::string fileName) + : fileName_(fileName), refCount_(0), pkgManager_(pkgManager) {} virtual ~PkgStreamImpl() {} @@ -68,16 +69,18 @@ public: static PkgStreamPtr ConvertPkgStream(PkgManager::StreamPtr stream); protected: + void PostDecodeProgress(int type, size_t writeDataLen, const void *context); std::string fileName_; private: std::atomic_int refCount_; + PkgManager::PkgManagerPtr pkgManager_ = nullptr; }; class FileStream : public PkgStreamImpl { public: - FileStream(std::string fileName, FILE *stream, int32_t streamType) : PkgStreamImpl(fileName), - stream_(stream), fileLength_(0), streamType_(streamType) {} + FileStream(PkgManager::PkgManagerPtr pkgManager, std::string fileName, FILE *stream, int32_t streamType) + : PkgStreamImpl(pkgManager, fileName), stream_(stream), fileLength_(0), streamType_(streamType) {} ~FileStream() override; @@ -103,8 +106,8 @@ private: class MemoryMapStream : public PkgStreamImpl { public: - MemoryMapStream(std::string fileName, const PkgBuffer &buffer, - int32_t streamType = PkgStreamType_MemoryMap) : PkgStreamImpl(fileName), memMap_(buffer.buffer), + MemoryMapStream(PkgManager::PkgManagerPtr pkgManager, std::string fileName, const PkgBuffer &buffer, + int32_t streamType = PkgStreamType_MemoryMap) : PkgStreamImpl(pkgManager, fileName), memMap_(buffer.buffer), memSize_(buffer.length), currOffset_(0), streamType_(streamType) {} ~MemoryMapStream() override; @@ -151,8 +154,9 @@ private: class ProcessorStream : public PkgStreamImpl { public: - ProcessorStream(std::string fileName, ExtractFileProcessor processor, const void *context) - : PkgStreamImpl(fileName), processor_(processor), context_(context) {} + ProcessorStream(PkgManager::PkgManagerPtr pkgManager, std::string fileName, + ExtractFileProcessor processor, const void *context) + : PkgStreamImpl(pkgManager, fileName), processor_(processor), context_(context) {} ~ProcessorStream() override {} @@ -168,7 +172,9 @@ public: int32_t Write(const PkgBuffer &data, size_t size, size_t start) override { PKG_CHECK(processor_ != nullptr, return PKG_INVALID_STREAM, "processor not exist"); - return processor_(data, size, start, false, context_); + int ret = processor_(data, size, start, false, context_); + PostDecodeProgress(POST_TYPE_DECODE_PKG, size, nullptr); + return ret; } int32_t Seek(long int size, int whence) override diff --git a/services/package/pkg_package/pkg_gzipfile.h b/services/package/pkg_package/pkg_gzipfile.h index 8d14f3ac..a06dd7e5 100644 --- a/services/package/pkg_package/pkg_gzipfile.h +++ b/services/package/pkg_package/pkg_gzipfile.h @@ -56,7 +56,8 @@ private: class GZipPkgFile : public PkgFile { public: - explicit GZipPkgFile(PkgStreamPtr stream) : PkgFile(stream, PkgFile::PKG_TYPE_GZIP) + explicit GZipPkgFile(PkgManager::PkgManagerPtr manager, PkgStreamPtr stream) + : PkgFile(manager, stream, PkgFile::PKG_TYPE_GZIP) { pkgInfo_.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo_.digestMethod = PKG_DIGEST_TYPE_SHA256; diff --git a/services/package/pkg_package/pkg_lz4file.h b/services/package/pkg_package/pkg_lz4file.h index 24425529..95b0658a 100644 --- a/services/package/pkg_package/pkg_lz4file.h +++ b/services/package/pkg_package/pkg_lz4file.h @@ -52,7 +52,8 @@ private: class Lz4PkgFile : public PkgFile { public: - explicit Lz4PkgFile(PkgStreamPtr stream) : PkgFile(stream, PkgFile::PKG_TYPE_LZ4) + explicit Lz4PkgFile(PkgManager::PkgManagerPtr manager, PkgStreamPtr stream) + : PkgFile(manager, stream, PkgFile::PKG_TYPE_LZ4) { pkgInfo_.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo_.digestMethod = PKG_DIGEST_TYPE_SHA256; diff --git a/services/package/pkg_package/pkg_pkgfile.cpp b/services/package/pkg_package/pkg_pkgfile.cpp index 5deac71e..c02e9d8c 100644 --- a/services/package/pkg_package/pkg_pkgfile.cpp +++ b/services/package/pkg_package/pkg_pkgfile.cpp @@ -34,6 +34,8 @@ PkgFile::~PkgFile() } pkgEntryMapId_.clear(); pkgEntryMapFileName_.clear(); + PkgManager::StreamPtr tmpStream = pkgStream_; + pkgManager_->ClosePkgStream(tmpStream); } PkgEntryPtr PkgFile::AddPkgEntry(const std::string &fileName) diff --git a/services/package/pkg_package/pkg_pkgfile.h b/services/package/pkg_package/pkg_pkgfile.h index e48b2369..7a7a908d 100644 --- a/services/package/pkg_package/pkg_pkgfile.h +++ b/services/package/pkg_package/pkg_pkgfile.h @@ -85,7 +85,8 @@ public: const std::vector &digest, const std::vector &signature)>; public: - PkgFile(PkgStreamPtr stream, PkgType type) : type_(type), pkgStream_(stream) {} + PkgFile(PkgManager::PkgManagerPtr manager, PkgStreamPtr stream, PkgType type) + : type_(type), pkgStream_(stream), pkgManager_(manager) {} virtual ~PkgFile(); @@ -136,6 +137,7 @@ protected: PkgType type_ {}; PkgStreamPtr pkgStream_ = nullptr; + PkgManager::PkgManagerPtr pkgManager_ = nullptr; uint32_t nodeId_ = 0; std::map pkgEntryMapId_ {}; std::multimap> pkgEntryMapFileName_ {}; diff --git a/services/package/pkg_package/pkg_upgradefile.cpp b/services/package/pkg_package/pkg_upgradefile.cpp index 8ca02378..85d4e1e0 100644 --- a/services/package/pkg_package/pkg_upgradefile.cpp +++ b/services/package/pkg_package/pkg_upgradefile.cpp @@ -233,6 +233,7 @@ int32_t UpgradePkgFile::Verify(size_t start, DigestAlgorithm::DigestAlgorithmPtr ret = pkgStream_->Read(buffer, offset, remainBytes, readBytes); PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail to read data "); algorithm->Update(buffer, readBytes); + pkgManager_->PostDecodeProgress(POST_TYPE_VERIFY_PKG, remainBytes, nullptr); } PkgBuffer digest(GetDigestLen()); diff --git a/services/package/pkg_package/pkg_upgradefile.h b/services/package/pkg_package/pkg_upgradefile.h index 93a8ec61..e2fdbb27 100644 --- a/services/package/pkg_package/pkg_upgradefile.h +++ b/services/package/pkg_package/pkg_upgradefile.h @@ -78,8 +78,8 @@ private: class UpgradePkgFile : public PkgFile { public: - UpgradePkgFile(PkgStreamPtr stream, PkgManager::PkgInfoPtr header) : - PkgFile(stream, PkgFile::PKG_TYPE_UPGRADE) + UpgradePkgFile(PkgManager::PkgManagerPtr manager, PkgStreamPtr stream, PkgManager::PkgInfoPtr header) + : PkgFile(manager, stream, PkgFile::PKG_TYPE_UPGRADE) { if (header == nullptr || header->entryCount == 0) { return; @@ -92,7 +92,7 @@ public: int32_t AddEntry(const PkgManager::FileInfoPtr file, const PkgStreamPtr input) override; - int32_t SavePackage(size_t &offset) override; + int32_t SavePackage(size_t &signOffset) override; int32_t LoadPackage(std::vector &fileNames, VerifyFunction verify = nullptr) override; diff --git a/services/package/pkg_package/pkg_zipfile.h b/services/package/pkg_package/pkg_zipfile.h index 01ef177e..706e5715 100644 --- a/services/package/pkg_package/pkg_zipfile.h +++ b/services/package/pkg_package/pkg_zipfile.h @@ -168,7 +168,8 @@ private: class ZipPkgFile : public PkgFile { public: - explicit ZipPkgFile(PkgStreamPtr stream) : PkgFile(stream, PkgFile::PKG_TYPE_ZIP) + explicit ZipPkgFile(PkgManager::PkgManagerPtr manager, PkgStreamPtr stream) + : PkgFile(manager, stream, PkgFile::PKG_TYPE_ZIP) { pkgInfo_.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo_.digestMethod = PKG_DIGEST_TYPE_SHA256; diff --git a/services/ui/surface_dev.cpp b/services/ui/surface_dev.cpp index 73de0f69..fbfb53c0 100644 --- a/services/ui/surface_dev.cpp +++ b/services/ui/surface_dev.cpp @@ -17,7 +17,7 @@ #include "updater_ui_const.h" namespace updater { -void SurfaceDev::Flip(void *buf) +void SurfaceDev::Flip(const void *buf) { if (!buf) { LOG(ERROR) << "buf is null"; diff --git a/services/ui/surface_dev.h b/services/ui/surface_dev.h index cc7c47ac..d65d1a65 100644 --- a/services/ui/surface_dev.h +++ b/services/ui/surface_dev.h @@ -25,9 +25,9 @@ public: DRM_DEVICE, }; - explicit SurfaceDev(SurfaceDev::DevType deviceType); + explicit SurfaceDev(SurfaceDev::DevType devType); ~SurfaceDev() override; - void Flip(void* buf); + void Flip(const void* buf); void GetScreenSize(int &w, int &h); private: int screenSizeW_ = 0; diff --git a/services/ui/updater_ui.cpp b/services/ui/updater_ui.cpp index 15957511..bf15c482 100644 --- a/services/ui/updater_ui.cpp +++ b/services/ui/updater_ui.cpp @@ -518,4 +518,19 @@ void DeleteView() g_sfDev = nullptr; } } + +TextLabel *GetUpdateInfoLabel() +{ + return g_updateInfoLabel; +} + +ProgressBar *GetProgressBar() +{ + return g_progressBar; +} + +void SetUpdateFlag(int updateFlag) +{ + g_updateFlag = updateFlag; +} } // namespace updater diff --git a/services/ui/updater_ui.h b/services/ui/updater_ui.h index d495aa16..621df1c3 100644 --- a/services/ui/updater_ui.h +++ b/services/ui/updater_ui.h @@ -17,6 +17,7 @@ #include #include "text_label.h" +#include "progress_bar.h" namespace updater { void DoProgress(); @@ -28,5 +29,11 @@ void UpdaterUiInit(); void ShowText(TextLabel *label, std::string text); void DeleteView(); + +TextLabel *GetUpdateInfoLabel(); + +ProgressBar *GetProgressBar(); + +void SetUpdateFlag(int updateFlag); } // namespace updater #endif /* UPDATE_UI_HOS_UPDATER_H */ diff --git a/services/updater.cpp b/services/updater.cpp index 44531918..caccbbfe 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -42,9 +42,6 @@ using updater::utils::SplitString; using updater::utils::Trim; using namespace hpackage; -extern TextLabel *g_updateInfoLabel; -extern ProgressBar *g_progressBar; - int g_percentage; int g_tmpProgressValue; int g_tmpValue; @@ -116,39 +113,7 @@ int UpdatePreProcess(PkgManager::PkgManagerPtr pkgManager, const std::string &pa return ret; } -static UpdaterStatus IsSpaceCapacitySufficient(const std::string &packagePath) -{ - PkgManager::PkgManagerPtr pkgManager = hpackage::PkgManager::CreatePackageInstance(); - UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return UPDATE_CORRUPT); - std::vector fileIds; - int ret = pkgManager->LoadPackageWithoutUnPack(packagePath, fileIds); - UPDATER_ERROR_CHECK(ret == PKG_SUCCESS, "LoadPackageWithoutUnPack failed", - PkgManager::ReleasePackageInstance(pkgManager); return UPDATE_CORRUPT); - - const FileInfo *info = pkgManager->GetFileInfo("update.bin"); - UPDATER_ERROR_CHECK(info != nullptr, "update.bin is not exist", - PkgManager::ReleasePackageInstance(pkgManager); return UPDATE_CORRUPT); - PkgManager::ReleasePackageInstance(pkgManager); - - struct statvfs64 updaterVfs; - if (access("/sdcard/updater", 0) == 0) { - UPDATER_ERROR_CHECK(statvfs64("/sdcard", &updaterVfs) >= 0, "Statvfs read /sdcard error!", return UPDATE_ERROR); - auto freeSpaceSize = static_cast(updaterVfs.f_bfree); - auto blockSize = static_cast(updaterVfs.f_bsize); - uint64_t totalFreeSize = freeSpaceSize * blockSize; - UPDATER_ERROR_CHECK(totalFreeSize > static_cast(info->unpackedSize), - "Can not update, free space is not enough", - ShowText(g_updateInfoLabel, "Free space is not enough"); return UPDATE_ERROR); - } else { - UPDATER_ERROR_CHECK(statvfs64("/data", &updaterVfs) >= 0, "Statvfs read /data error!", return UPDATE_ERROR); - UPDATER_ERROR_CHECK(updaterVfs.f_bfree * updaterVfs.f_bsize > (info->unpackedSize + MAX_LOG_SPACE), - "Can not update, free space is not enough", - ShowText(g_updateInfoLabel, "Free space is not enough"); return UPDATE_ERROR); - } - return UPDATE_SUCCESS; -} - -static inline void ProgressSmoothHandler() +static void ProgressSmoothHandler() { while (g_tmpProgressValue < FULL_PERCENT_PROGRESS) { int gap = FULL_PERCENT_PROGRESS - g_tmpProgressValue; @@ -157,7 +122,9 @@ static inline void ProgressSmoothHandler() if (g_tmpProgressValue >= FULL_PERCENT_PROGRESS || increase == 0) { break; } else { - g_progressBar->SetProgressValue(g_tmpProgressValue); + if (GetProgressBar() != nullptr) { + GetProgressBar()->SetProgressValue(g_tmpProgressValue); + } std::this_thread::sleep_for(std::chrono::milliseconds(SHOW_FULL_PROGRESS_TIME)); } } @@ -166,23 +133,29 @@ static inline void ProgressSmoothHandler() UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, const std::string &packagePath, int retryCount) { - g_progressBar->Hide(); + if (GetProgressBar() != nullptr) { + GetProgressBar()->Hide(); + } ShowUpdateFrame(true); UPDATER_ERROR_CHECK(pkgManager != nullptr, "Fail to GetPackageInstance", return UPDATE_CORRUPT); + TextLabel *updateInfoLabel = GetUpdateInfoLabel(); + UPDATER_ERROR_CHECK(updateInfoLabel != nullptr, "Fail to updateInfoLabel", return UPDATE_CORRUPT); LOG(INFO) << "Verify package..."; - g_updateInfoLabel->SetText("Verify package..."); + updateInfoLabel->SetText("Verify package..."); UPDATER_ERROR_CHECK(access(packagePath.c_str(), 0) == 0, "package is not exist", - ShowText(g_updateInfoLabel, "package is not exist"); return UPDATE_CORRUPT); + ShowText(GetUpdateInfoLabel(), "package is not exist"); return UPDATE_CORRUPT); if (retryCount > 0) { LOG(INFO) << "Retry for " << retryCount << " time(s)"; } else { - UpdaterStatus ret = IsSpaceCapacitySufficient(packagePath); + UpdaterStatus ret = static_cast(IsSpaceCapacitySufficient(packagePath)); // Only handle UPATE_ERROR and UPDATE_SUCCESS here. // If it returns UPDATE_CORRUPT, which means something wrong with package manager. // Let package verify handle this. - if (ret == UPDATE_ERROR) { + if (ret == UPDATE_SPACE_NOTENOUGH) { + ShowText(GetUpdateInfoLabel(), "Free space is not enough"); + } else if (ret == UPDATE_ERROR) { return ret; } else if (ret == UPDATE_SUCCESS) { pkgManager = PkgManager::GetPackageInstance(); @@ -191,7 +164,7 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons int32_t verifyret = GetUpdatePackageInfo(pkgManager, packagePath); UPDATER_ERROR_CHECK(verifyret == PKG_SUCCESS, "Verify package Fail...", - ShowText(g_updateInfoLabel, "Verify package Fail..."); return UPDATE_CORRUPT); + ShowText(GetUpdateInfoLabel(), "Verify package Fail..."); return UPDATE_CORRUPT); LOG(INFO) << "Package verified. start to install package..."; int32_t versionRet = UpdatePreProcess(pkgManager, packagePath); UPDATER_ERROR_CHECK(versionRet == PKG_SUCCESS, "Version Check Fail...", return UPDATE_CORRUPT); @@ -200,21 +173,49 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons UpdaterStatus updateRet = StartUpdaterProc(pkgManager, packagePath, retryCount, maxTemperature); if (updateRet == UPDATE_SUCCESS) { ProgressSmoothHandler(); - g_progressBar->SetProgressValue(FULL_PERCENT_PROGRESS); - g_updateInfoLabel->SetText("Update success, reboot now"); + if (GetProgressBar() != nullptr) { + GetProgressBar()->SetProgressValue(FULL_PERCENT_PROGRESS); + } + updateInfoLabel->SetText("Update success, reboot now"); std::this_thread::sleep_for(std::chrono::milliseconds(SHOW_FULL_PROGRESS_TIME)); LOG(INFO)<< "update success , do reboot now"; } else { - g_updateInfoLabel->SetText("Install failed."); + updateInfoLabel->SetText("Install failed."); LOG(ERROR) << "Install package failed."; } return updateRet; } +static void HandleProgressSet(const std::vector &output) +{ + UPDATER_ERROR_CHECK(output.size() >= DEFAULT_PROCESS_NUM, "check output fail", return); + auto outputInfo = Trim(output[1]); + float frac = 0.0; + frac = std::stof(output[1]); + if (frac >= -EPSINON && frac <= EPSINON) { + return; + } else { + g_tmpProgressValue = static_cast(frac * g_percentage); + } + if (frac >= FULL_EPSINON && g_tmpValue + g_percentage < FULL_PERCENT_PROGRESS) { + g_tmpValue += g_percentage; + return; + } + g_tmpProgressValue = g_tmpProgressValue + g_tmpValue; + if (g_tmpProgressValue == 0) { + return; + } + if (GetProgressBar() != nullptr) { + GetProgressBar()->SetProgressValue(g_tmpProgressValue); + } +} static void HandleChildOutput(const std::string &buffer, int32_t bufferLen, bool &retryUpdate) { UPDATER_CHECK_ONLY_RETURN(bufferLen != 0, return); + TextLabel *updateInfoLabel = GetUpdateInfoLabel(); + UPDATER_ERROR_CHECK(updateInfoLabel != nullptr, "Fail to updateInfoLabel", return); + std::string str = buffer; std::vector output = SplitString(str, ":"); UPDATER_ERROR_CHECK(output.size() >= 1, "check output fail", return); @@ -236,32 +237,17 @@ static void HandleChildOutput(const std::string &buffer, int32_t bufferLen, if (progress.size() != DEFAULT_PROCESS_NUM) { LOG(ERROR) << "show progress with wrong arguments"; } else { - g_progressBar->Show(); - g_updateInfoLabel->SetText("Start to install package."); + if (GetProgressBar() != nullptr) { + GetProgressBar()->Show(); + } + updateInfoLabel->SetText("Start to install package."); frac = std::stof(progress[0]); g_percentage = static_cast(frac * FULL_PERCENT_PROGRESS); } } else if (outputHeader == "set_progress") { - UPDATER_ERROR_CHECK(output.size() >= DEFAULT_PROCESS_NUM, "check output fail", return); - auto outputInfo = Trim(output[1]); - float frac = 0.0; - frac = std::stof(output[1]); - if (frac >= -EPSINON && frac <= EPSINON) { - return; - } else { - g_tmpProgressValue = static_cast(frac * g_percentage); - } - if (frac >= FULL_EPSINON && g_tmpValue + g_percentage < FULL_PERCENT_PROGRESS) { - g_tmpValue += g_percentage; - return; - } - g_tmpProgressValue = g_tmpProgressValue + g_tmpValue; - if (g_tmpProgressValue == 0) { - return; - } - g_progressBar->SetProgressValue(g_tmpProgressValue); + HandleProgressSet(output); } else { - LOG(WARNING) << "Child process returns unexpected message."; + LOG(DEBUG) << "Child process returns unexpected message: " << outputHeader; } } @@ -273,12 +259,11 @@ UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, const std:: UPDATER_ERROR_CHECK(pkgManager != nullptr, "Fail to GetPackageInstance", return UPDATE_CORRUPT); int pipeRead = pfd[0]; int pipeWrite = pfd[1]; - UPDATER_ERROR_CHECK(ExtractUpdaterBinary(pkgManager, UPDATER_BINARY) == 0, "Updater: cannot extract updater binary from update package.", return UPDATE_CORRUPT); g_tmpProgressValue = 0; - if (g_progressBar != nullptr) { - g_progressBar->SetProgressValue(0); + if (GetProgressBar() != nullptr) { + GetProgressBar()->SetProgressValue(0); } pid_t pid = fork(); UPDATER_CHECK_ONLY_RETURN(pid >= 0, ERROR_CODE(CODE_FORK_FAIL); return UPDATE_ERROR); @@ -319,7 +304,7 @@ UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, const std:: } close(pipeWrite); // close write endpoint - char buffer[MAX_BUFFER_SIZE]; + char buffer[MAX_BUFFER_SIZE] = {0}; bool retryUpdate = false; FILE* fromChild = fdopen(pipeRead, "r"); UPDATER_ERROR_CHECK(fromChild != nullptr, "fdopen pipeRead failed", return UPDATE_ERROR); diff --git a/services/updater_binary/BUILD.gn b/services/updater_binary/BUILD.gn index 1a242386..6c2a2237 100644 --- a/services/updater_binary/BUILD.gn +++ b/services/updater_binary/BUILD.gn @@ -27,6 +27,7 @@ config("updater_config") { "//third_party/openssl/include", "//third_party/bounds_checking_function/include", "//drivers/hdf/frameworks/include/utils", + "//base/startup/init_lite/interfaces/innerkits/include", ] } diff --git a/services/updater_binary/main.cpp b/services/updater_binary/main.cpp index 6f145ce3..775c17c1 100644 --- a/services/updater_binary/main.cpp +++ b/services/updater_binary/main.cpp @@ -24,6 +24,7 @@ #include "utils.h" using namespace updater; +#ifndef UPDATER_UT int main(int argc, char **argv) { InitUpdaterLogger("UPDATER_BINARY", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); @@ -42,3 +43,4 @@ int main(int argc, char **argv) std::string packagePath = argv[0]; return ProcessUpdater(retry, pipeFd, packagePath, utils::GetCertName()); } +#endif \ No newline at end of file diff --git a/services/updater_binary/update_partitions.cpp b/services/updater_binary/update_partitions.cpp index 0f431deb..edd7fcab 100644 --- a/services/updater_binary/update_partitions.cpp +++ b/services/updater_binary/update_partitions.cpp @@ -85,7 +85,7 @@ int UpdatePartitions::DoNewPartitions(PartitonList &newPartList) if (ret <= 0) { LOG(INFO) << "do_partitions FAIL "; } else if (ret == 1) { - LOG(INFO) << "partitions not changed,Skip. "; + LOG(INFO) << "partitions not changed, Skip"; } else if (ret > 1) { LOG(INFO) << "do_partitions success reboot"; #ifndef UPDATER_UT diff --git a/services/updater_binary/update_processor.cpp b/services/updater_binary/update_processor.cpp index 270c8c4f..34675148 100644 --- a/services/updater_binary/update_processor.cpp +++ b/services/updater_binary/update_processor.cpp @@ -43,8 +43,8 @@ UpdaterEnv::~UpdaterEnv() void UpdaterEnv::PostMessage(const std::string &cmd, std::string content) { - if (pipeWrite_ != nullptr) { - fprintf(pipeWrite_, "%s:%s\n", cmd.c_str(), content.c_str()); + if (postMessage_ != nullptr) { + postMessage_(cmd.c_str(), content.c_str()); } } @@ -108,6 +108,7 @@ int UScriptInstructionRawImageWrite::RawImageWriteProcessor(const PkgBuffer &buf if (totalSize_ != 0) { readSize_ += size; writer->GetUpdaterEnv()->PostMessage("set_progress", std::to_string((float)readSize_ / totalSize_)); + writer->GetUpdaterEnv()->PostMessage("data", std::to_string(size)); } return PKG_SUCCESS; @@ -212,6 +213,25 @@ int32_t UScriptInstructionSparseImageWrite::Execute(uscript::UScriptEnv &env, us DataWriter::ReleaseDataWriter(writer); return ret; } + +int ExecUpdate(PkgManager::PkgManagerPtr pkgManager, int retry, PostMessageFunction postMessage) +{ + UpdaterEnv* env = new UpdaterEnv(pkgManager, postMessage, retry); + UPDATER_ERROR_CHECK(env != nullptr, "Fail to create env", return EXIT_PARSE_SCRIPT_ERROR); + int ret = 0; + ScriptManager* scriptManager = ScriptManager::GetScriptManager(env); + UPDATER_ERROR_CHECK(scriptManager != nullptr, "Fail to create scriptManager", + ScriptManager::ReleaseScriptManager(); + delete env; + return EXIT_PARSE_SCRIPT_ERROR); + for (int32_t i = 0; i < ScriptManager::MAX_PRIORITY; i++) { + ret = scriptManager->ExecuteScript(i); + UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS, "Fail to execute script", break); + } + ScriptManager::ReleaseScriptManager(); + delete env; + return ret; +} } // updater int ProcessUpdater(bool retry, int pipeFd, const std::string &packagePath, const std::string &keyPath) @@ -227,35 +247,15 @@ int ProcessUpdater(bool retry, int pipeFd, const std::string &packagePath, const std::vector components; int32_t ret = pkgManager->LoadPackage(packagePath, keyPath, components); UPDATER_ERROR_CHECK(ret == PKG_SUCCESS, "Fail to load package", - fclose(pipeWrite); - pipeWrite = nullptr; PkgManager::ReleasePackageInstance(pkgManager); return EXIT_INVALID_ARGS); - UpdaterEnv* env = new UpdaterEnv(pkgManager, pipeWrite, retry); - UPDATER_ERROR_CHECK(env != nullptr, "Fail to create env", - fclose(pipeWrite); - pipeWrite = nullptr; - PkgManager::ReleasePackageInstance(pkgManager); - env = nullptr; - return EXIT_PARSE_SCRIPT_ERROR); - ScriptManager* scriptManager = ScriptManager::GetScriptManager(env); - UPDATER_ERROR_CHECK(scriptManager != nullptr, "Fail to create scriptManager", - fclose(pipeWrite); - pipeWrite = nullptr; - delete env; - env = nullptr; - PkgManager::ReleasePackageInstance(pkgManager); - ScriptManager::ReleaseScriptManager(); - return EXIT_PARSE_SCRIPT_ERROR); - for (int32_t i = 0; i < ScriptManager::MAX_PRIORITY; i++) { - ret = scriptManager->ExecuteScript(i); - UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS, "Fail to execute script", break); - } - - delete env; - env = nullptr; - ScriptManager::ReleaseScriptManager(); + ret = updater::ExecUpdate(pkgManager, retry, + [&pipeWrite](const char *cmd, const char *content) { + if (pipeWrite != nullptr) { + fprintf(pipeWrite, "%s:%s\n", cmd, content); + } + }); PkgManager::ReleasePackageInstance(pkgManager); #ifndef UPDATER_UT fclose(pipeWrite); diff --git a/services/updater_main.cpp b/services/updater_main.cpp index f90b73e6..c4b40a2c 100644 --- a/services/updater_main.cpp +++ b/services/updater_main.cpp @@ -49,8 +49,7 @@ using namespace updater::utils; extern TextLabel *g_logLabel; extern TextLabel *g_logResultLabel; -extern TextLabel *g_updateInfoLabel; -extern int g_updateFlag; + constexpr int DISPLAY_TIME = 1000 * 1000; constexpr struct option OPTIONS[] = { { "update_package", required_argument, nullptr, 0 }, @@ -103,20 +102,6 @@ int FactoryReset(FactoryResetMode mode, const std::string &path) return DoFactoryReset(mode, path); } - -bool IsSDCardExist(const std::string &sdcardPath) -{ - // Record system error codes. - int save_errno = errno; - struct stat st {}; - if (stat(sdcardPath.c_str(), &st) < 0) { - return false; - } else { - errno = save_errno; - return true; - } -} - UpdaterStatus UpdaterFromSdcard() { #ifndef UPDATER_UT @@ -130,7 +115,6 @@ UpdaterStatus UpdaterFromSdcard() } return UPDATE_ERROR; } - if (MountForPath(SDCARD_PATH) != 0) { int ret = mount(sdcardStr.c_str(), SDCARD_PATH.c_str(), "vfat", 0, NULL); UPDATER_WARING_CHECK(ret == 0, "MountForPath /sdcard failed!", return UPDATE_ERROR); @@ -181,7 +165,7 @@ static UpdaterStatus InstallUpdaterPackage(UpdaterParams &upParams, const std::v "ClearRecordPartitionOffset failed", return UPDATE_ERROR); SetRetryCountToMisc(upParams.retryCount + 1, args); } - UPDATER_CHECK_ONLY_RETURN(SetupPartitions() == 0, ShowText(g_updateInfoLabel, "Setup partitions failed"); + UPDATER_CHECK_ONLY_RETURN(SetupPartitions() == 0, ShowText(GetUpdateInfoLabel(), "Setup partitions failed"); return UPDATE_ERROR); status = DoInstallUpdaterPackage(manager, upParams.updatePackage, upParams.retryCount); if (status != UPDATE_SUCCESS) { @@ -213,7 +197,7 @@ static UpdaterStatus StartUpdaterEntry(PkgManager::PkgManagerPtr manager, } else if (upParams.factoryWipeData) { LOG(INFO) << "Factory level FactoryReset begin"; status = UPDATE_SUCCESS; - g_updateFlag = 1; + SetUpdateFlag(1); ShowUpdateFrame(true); DoProgress(); UPDATER_ERROR_CHECK(FactoryReset(FACTORY_WIPE_DATA, "/data") == 0, "FactoryReset factory level failed", @@ -228,7 +212,7 @@ static UpdaterStatus StartUpdaterEntry(PkgManager::PkgManagerPtr manager, } else if (upParams.userWipeData) { LOG(INFO) << "User level FactoryReset begin"; status = UPDATE_SUCCESS; - g_updateFlag = 1; + SetUpdateFlag(1); ShowUpdateFrame(true); DoProgress(); UPDATER_ERROR_CHECK(FactoryReset(USER_WIPE_DATA, "/data") == 0, "FactoryReset user level failed", @@ -291,138 +275,10 @@ static UpdaterStatus StartUpdater(PkgManager::PkgManagerPtr manager, const std:: return StartUpdaterEntry(manager, args, upParams); } -static bool IsDir(const std::string &path) -{ - struct stat st{}; - if (stat(path.c_str(), &st) < 0) { - return false; - } - return S_ISDIR(st.st_mode); -} - -static bool DeleteUpdaterPath(const std::string &path) -{ - auto pDir = std::unique_ptr(opendir(path.c_str()), closedir); - UPDATER_INFO_CHECK_NOT_RETURN(pDir != nullptr, "Can not open dir"); - - struct dirent *dp = nullptr; - if (pDir != nullptr) { - while ((dp = readdir(pDir.get())) != nullptr) { - std::string currentName(dp->d_name); - if (currentName[0] != '.' && (currentName.compare("log") != 0)) { - std::string tmpName(path); - tmpName.append("/" + currentName); - if (IsDir(tmpName)) { - DeleteUpdaterPath(tmpName); - } -#ifndef UPDATER_UT - remove(tmpName.c_str()); -#endif - } - } - } - return true; -} - -static bool ClearMisc() -{ - struct UpdateMessage cleanBoot {}; - UPDATER_ERROR_CHECK(WriteUpdaterMessage(MISC_FILE, cleanBoot) == true, - "ClearMisc clear boot message to misc failed", return false); - auto fp = std::unique_ptr(fopen(MISC_FILE.c_str(), "rb+"), fclose); - UPDATER_FILE_CHECK(fp != nullptr, "WriteVersionCode fopen failed", return false); - fseek(fp.get(), PARTITION_RECORD_OFFSET, SEEK_SET); - off_t clearOffset = 0; - UPDATER_FILE_CHECK(fwrite(&clearOffset, sizeof(off_t), 1, fp.get()) == 1, - "ClearMisc write misc initOffset 0 failed", return false); - - struct PartitionRecordInfo cleanPartition {}; - for (size_t tmpOffset = 0; tmpOffset < PARTITION_UPDATER_RECORD_MSG_SIZE; tmpOffset += - sizeof(PartitionRecordInfo)) { - fseek(fp.get(), PARTITION_RECORD_START + tmpOffset, SEEK_SET); - UPDATER_FILE_CHECK(fwrite(&cleanPartition, sizeof(PartitionRecordInfo), 1, fp.get()) == 1, - "ClearMisc write misc cleanPartition failed", return false); - } - return true; -} - -void PostUpdaterForSdcard(std::string &updaterLogPath, std::string &stageLogPath, std::string &errorCodePath) -{ - if (SetupPartitions() != 0) { - ShowText(g_updateInfoLabel, "Mount data failed."); - LOG(ERROR) << "Mount for /data failed."; - std::string sdcardPath = GetBlockDeviceByMountPoint(SDCARD_PATH); - if (IsSDCardExist(sdcardPath)) { - if (MountForPath(SDCARD_PATH) != 0) { - int ret = mount(sdcardPath.c_str(), SDCARD_PATH.c_str(), "vfat", 0, NULL); - UPDATER_WARING_CHECK(ret == 0, "Mount for /sdcard failed!", return); - } - updaterLogPath = "/sdcard/updater/log/updater_log"; - stageLogPath = "/sdcard/updater/log/updater_stage_log"; - errorCodePath = "/sdcard/updater/log/error_code.log"; - } - } - return; -} - -void PostUpdater() -{ - STAGE(UPDATE_STAGE_BEGIN) << "PostUpdater"; - std::string updaterLogPath = "/data/updater/log/updater_log"; - std::string stageLogPath = "/data/updater/log/updater_stage_log"; - std::string errorCodePath = "/data/updater/log/error_code.log"; - PostUpdaterForSdcard(updaterLogPath, stageLogPath, errorCodePath); - // clear update misc partition. - UPDATER_ERROR_CHECK_NOT_RETURN(ClearMisc() == true, "PostUpdater clear misc failed"); - if (!access(COMMAND_FILE.c_str(), 0)) { - UPDATER_ERROR_CHECK_NOT_RETURN(unlink(COMMAND_FILE.c_str()) == 0, "Delete command failed"); - } - - // delete updater tmp files - if (access(UPDATER_PATH.c_str(), 0) == 0 && access(SDCARD_CARD_PATH.c_str(), 0) != 0) { - UPDATER_ERROR_CHECK_NOT_RETURN(DeleteUpdaterPath(UPDATER_PATH), "DeleteUpdaterPath failed"); - } - if (!access(SDCARD_CARD_PATH.c_str(), 0)) { - UPDATER_ERROR_CHECK_NOT_RETURN(DeleteUpdaterPath(SDCARD_CARD_PATH), "Delete sdcard path failed"); - } - // save logs - UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_LOG, updaterLogPath) == true, "Copy updater log failed!"); - UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_ERROR_CODE_PATH, errorCodePath) == true, - "Copy error code log failed!"); - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - chmod(updaterLogPath.c_str(), mode); - chmod(stageLogPath.c_str(), mode); - chmod(errorCodePath.c_str(), mode); - STAGE(UPDATE_STAGE_SUCCESS) << "PostUpdater"; - UPDATER_ERROR_CHECK_NOT_RETURN(CopyUpdaterLogs(TMP_STAGE_LOG, stageLogPath) == true, "Copy stage log failed!"); -} - -std::vector ParseParams(int argc, char **argv) -{ - struct UpdateMessage boot {}; - // read from misc - UPDATER_ERROR_CHECK_NOT_RETURN(ReadUpdaterMessage(MISC_FILE, boot) == true, - "ReadUpdaterMessage MISC_FILE failed!"); - // if boot.update is empty, read from command.The Misc partition may have dirty data, - // so strlen(boot.update) is not used, which can cause system exceptions. - if (boot.update[0] == '\0' && !access(COMMAND_FILE.c_str(), 0)) { - UPDATER_ERROR_CHECK_NOT_RETURN(ReadUpdaterMessage(COMMAND_FILE, boot) == true, - "ReadUpdaterMessage COMMAND_FILE failed!"); - } - STAGE(UPDATE_STAGE_OUT) << "Init Params: " << boot.update; - std::vector parseParams(argv, argv + argc); - boot.update[sizeof(boot.update) - 1] = '\0'; - parseParams = utils::SplitString(boot.update, "\n"); - return parseParams; -} - int UpdaterMain(int argc, char **argv) { UpdaterStatus status = UPDATE_UNKNOWN; PkgManager::PkgManagerPtr manager = PkgManager::GetPackageInstance(); - InitUpdaterLogger("UPDATER", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); - SetLogLevel(INFO); - LoadFstab(); std::vector args = ParseParams(argc, argv); LOG(INFO) << "Ready to start"; diff --git a/services/updater_main.h b/services/updater_main.h index c2862850..fef8b7a8 100644 --- a/services/updater_main.h +++ b/services/updater_main.h @@ -35,10 +35,6 @@ struct UpdaterParams { int UpdaterMain(int argc, char **argv); -std::vector ParseParams(int argc, char **argv); - -void PostUpdater(); - int FactoryReset(FactoryResetMode mode, const std::string &path); UpdaterStatus UpdaterFromSdcard(); diff --git a/services/updater_utils.cpp b/services/updater_utils.cpp new file mode 100755 index 00000000..0abd3ca1 --- /dev/null +++ b/services/updater_utils.cpp @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include +#include +#include +#include +#include + +#include "applypatch/partition_record.h" +#include "flashd/flashd.h" +#include "log/log.h" +#include "misc_info/misc_info.h" +#include "package/pkg_manager.h" +#include "securec.h" +#include "updater/updater.h" +#include "updater/updater_const.h" +#include "updater_ui.h" +#include "utils.h" + +namespace updater { +using namespace hpackage; +using namespace updater::utils; +static constexpr int USER_ROOT_AUTHORITY = 0; +static constexpr int GROUP_SYS_AUTHORITY = 1000; + +void CompressLogs(const std::string &name) +{ + PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); + UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return); + std::vector> files; + // Build the zip file to be packaged + std::vector testFileNames; + std::string realName = name.substr(name.find_last_of("/") + 1); + testFileNames.push_back(realName); + for (auto name : testFileNames) { + ZipFileInfo file; + file.fileInfo.identity = name; + file.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP; + file.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC; + std::string fileName = "/data/updater/log/" + name; + files.push_back(std::pair(fileName, file)); + } + + PkgInfo pkgInfo; + pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; + pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; + pkgInfo.pkgType = PKG_PACK_TYPE_ZIP; + + char realTime[MAX_TIME_SIZE] = { 0 }; + auto sysTime = std::chrono::system_clock::now(); + auto currentTime = std::chrono::system_clock::to_time_t(sysTime); + struct tm *localTime = std::localtime(¤tTime); + if (localTime != nullptr) { + std::strftime(realTime, sizeof(realTime), "%H_%M_%S", localTime); + } + char pkgName[MAX_LOG_NAME_SIZE]; + UPDATER_CHECK_ONLY_RETURN(snprintf_s(pkgName, MAX_LOG_NAME_SIZE, MAX_LOG_NAME_SIZE - 1, + "/data/updater/log/%s_%s.zip", realName.c_str(), realTime) != -1, return); + int32_t ret = pkgManager->CreatePackage(pkgName, GetCertName(), &pkgInfo, files); + UPDATER_CHECK_ONLY_RETURN(ret != 0, return); + UPDATER_CHECK_ONLY_RETURN(DeleteFile(name) == 0, return); +} + +bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog) +{ + UPDATER_WARING_CHECK(MountForPath(UPDATER_LOG_DIR) == 0, "MountForPath /data/log failed!", return false); + if (access(UPDATER_LOG_DIR.c_str(), 0) != 0) { + UPDATER_ERROR_CHECK(!MkdirRecursive(UPDATER_LOG_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH), + "MkdirRecursive error!", return false); + UPDATER_ERROR_CHECK(chown(UPDATER_PATH.c_str(), USER_ROOT_AUTHORITY, GROUP_SYS_AUTHORITY) == 0, + "Chown failed!", return false); + UPDATER_ERROR_CHECK(chmod(UPDATER_PATH.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0, + "Chmod failed!", return false); + } + + FILE *dFp = fopen(dLog.c_str(), "ab+"); + UPDATER_ERROR_CHECK(dFp != nullptr, "open log failed", return false); + + FILE *sFp = fopen(sLog.c_str(), "r"); + UPDATER_ERROR_CHECK(sFp != nullptr, "open log failed", fclose(dFp); + return false); + + char buf[MAX_LOG_BUF_SIZE]; + size_t bytes; + while ((bytes = fread(buf, 1, sizeof(buf), sFp)) != 0) { + int ret = fwrite(buf, 1, bytes, dFp); + if (ret < 0) { + break; + } + } + (void)fseek(dFp, 0, SEEK_END); + UPDATER_INFO_CHECK(ftell(dFp) < MAX_LOG_SIZE, "log size greater than 5M!", CompressLogs(dLog)); + sync(); + (void)fclose(sFp); + (void)fclose(dFp); + return true; +} + +static bool IsDir(const std::string &path) +{ + struct stat st {}; + if (stat(path.c_str(), &st) < 0) { + return false; + } + return S_ISDIR(st.st_mode); +} + +static bool DeleteUpdaterPath(const std::string &path) +{ + auto pDir = std::unique_ptr(opendir(path.c_str()), closedir); + UPDATER_INFO_CHECK_NOT_RETURN(pDir != nullptr, "Can not open dir"); + if (pDir == nullptr) { + return true; + } + struct dirent *dp = nullptr; + while ((dp = readdir(pDir.get())) != nullptr) { + std::string currentName(dp->d_name); + if (currentName[0] != '.' && (currentName.compare("log") != 0)) { + std::string tmpName(path); + tmpName.append("/" + currentName); + if (IsDir(tmpName)) { + DeleteUpdaterPath(tmpName); + } +#ifndef UPDATER_UT + remove(tmpName.c_str()); +#endif + } + } + return true; +} + +static bool ClearMisc() +{ + struct UpdateMessage cleanBoot {}; + UPDATER_ERROR_CHECK(WriteUpdaterMessage(MISC_FILE, cleanBoot) == true, + "ClearMisc clear boot message to misc failed", return false); + auto fp = std::unique_ptr(fopen(MISC_FILE.c_str(), "rb+"), fclose); + UPDATER_FILE_CHECK(fp != nullptr, "WriteVersionCode fopen failed", return false); + (void)fseek(fp.get(), PARTITION_RECORD_OFFSET, SEEK_SET); + off_t clearOffset = 0; + UPDATER_FILE_CHECK(fwrite(&clearOffset, sizeof(off_t), 1, fp.get()) == 1, + "ClearMisc write misc initOffset 0 failed", return false); + + struct PartitionRecordInfo cleanPartition {}; + for (size_t tmpOffset = 0; tmpOffset < PARTITION_UPDATER_RECORD_MSG_SIZE; tmpOffset += + sizeof(PartitionRecordInfo)) { + (void)fseek(fp.get(), PARTITION_RECORD_START + tmpOffset, SEEK_SET); + UPDATER_FILE_CHECK(fwrite(&cleanPartition, sizeof(PartitionRecordInfo), 1, fp.get()) == 1, + "ClearMisc write misc cleanPartition failed", return false); + } + return true; +} + +bool IsSDCardExist(const std::string &sdcardPath) +{ + // Record system error codes. + int save_errno = errno; + struct stat st {}; + if (stat(sdcardPath.c_str(), &st) < 0) { + return false; + } else { + errno = save_errno; + return true; + } +} + +void PostUpdaterForSdcard(std::string &updaterLogPath, std::string &stageLogPath, std::string &errorCodePath) +{ + if (SetupPartitions() != 0) { + ShowText(GetUpdateInfoLabel(), "Mount data failed."); + LOG(ERROR) << "Mount for /data failed."; + std::string sdcardPath = GetBlockDeviceByMountPoint(SDCARD_PATH); + if (IsSDCardExist(sdcardPath)) { + if (MountForPath(SDCARD_PATH) != 0) { + int ret = mount(sdcardPath.c_str(), SDCARD_PATH.c_str(), "vfat", 0, NULL); + UPDATER_WARING_CHECK(ret == 0, "Mount for /sdcard failed!", return); + } + updaterLogPath = "/sdcard/updater/log/updater_log"; + stageLogPath = "/sdcard/updater/log/updater_stage_log"; + errorCodePath = "/sdcard/updater/log/error_code.log"; + } + } + return; +} + +void PostUpdater() +{ + STAGE(UPDATE_STAGE_BEGIN) << "PostUpdater"; + std::string updaterLogPath = "/data/updater/log/updater_log"; + std::string stageLogPath = "/data/updater/log/updater_stage_log"; + std::string errorCodePath = "/data/updater/log/error_code.log"; + PostUpdaterForSdcard(updaterLogPath, stageLogPath, errorCodePath); + // clear update misc partition. + UPDATER_ERROR_CHECK_NOT_RETURN(ClearMisc() == true, "PostUpdater clear misc failed"); + if (!access(COMMAND_FILE.c_str(), 0)) { + UPDATER_ERROR_CHECK_NOT_RETURN(unlink(COMMAND_FILE.c_str()) == 0, "Delete command failed"); + } + + // delete updater tmp files + if (access(UPDATER_PATH.c_str(), 0) == 0 && access(SDCARD_CARD_PATH.c_str(), 0) != 0) { + UPDATER_ERROR_CHECK_NOT_RETURN(DeleteUpdaterPath(UPDATER_PATH), "DeleteUpdaterPath failed"); + } + if (!access(SDCARD_CARD_PATH.c_str(), 0)) { + UPDATER_ERROR_CHECK_NOT_RETURN(DeleteUpdaterPath(SDCARD_CARD_PATH), "Delete sdcard path failed"); + } + if (access(flashd::FLASHD_FILE_PATH.c_str(), 0) == 0) { + UPDATER_ERROR_CHECK_NOT_RETURN(DeleteUpdaterPath(flashd::FLASHD_FILE_PATH), "DeleteUpdaterPath failed"); + } + + // save logs + bool ret = CopyUpdaterLogs(TMP_LOG, updaterLogPath); + UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Copy updater log failed!"); + ret = CopyUpdaterLogs(TMP_ERROR_CODE_PATH, errorCodePath); + UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Copy error code log failed!"); + ret = CopyUpdaterLogs(flashd::FLASHD_HDC_LOG_PATH, UPDATER_HDC_LOG); + UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Copy error hdc log failed!"); + + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + chmod(updaterLogPath.c_str(), mode); + chmod(stageLogPath.c_str(), mode); + chmod(errorCodePath.c_str(), mode); + STAGE(UPDATE_STAGE_SUCCESS) << "PostUpdater"; + ret = CopyUpdaterLogs(TMP_STAGE_LOG, stageLogPath); + UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Copy stage log failed!"); +} + +int IsSpaceCapacitySufficient(const std::string &packagePath) +{ + hpackage::PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance(); + UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return UPDATE_CORRUPT); + std::vector fileIds; + int ret = pkgManager->LoadPackageWithoutUnPack(packagePath, fileIds); + UPDATER_ERROR_CHECK(ret == PKG_SUCCESS, "LoadPackageWithoutUnPack failed", + PkgManager::ReleasePackageInstance(pkgManager); return UPDATE_CORRUPT); + const FileInfo *info = pkgManager->GetFileInfo("update.bin"); + UPDATER_ERROR_CHECK(info != nullptr, "update.bin is not exist", + PkgManager::ReleasePackageInstance(pkgManager); return UPDATE_CORRUPT); + uint64_t needSpace = static_cast(info->unpackedSize); + PkgManager::ReleasePackageInstance(pkgManager); + + struct statvfs64 updaterVfs {}; + if (strncmp(packagePath.c_str(), SDCARD_CARD_PATH.c_str(), SDCARD_CARD_PATH.size()) == 0) { // for sdcard + ret = statvfs64(SDCARD_PATH.c_str(), &updaterVfs); + UPDATER_ERROR_CHECK(ret >= 0, "Statvfs read /sdcard error!", return UPDATE_ERROR); + } else { + needSpace += MAX_LOG_SPACE; + ret = statvfs64(UPDATER_PATH.c_str(), &updaterVfs); + UPDATER_ERROR_CHECK(ret >= 0, "Statvfs read /data error!", return UPDATE_ERROR); + } + auto freeSpaceSize = static_cast(updaterVfs.f_bfree); + auto blockSize = static_cast(updaterVfs.f_bsize); + uint64_t totalFreeSize = freeSpaceSize * blockSize; + UPDATER_ERROR_CHECK(totalFreeSize > needSpace, + "Can not update, free space is not enough", return UPDATE_SPACE_NOTENOUGH); + return UPDATE_SUCCESS; +} + +std::vector ParseParams(int argc, char **argv) +{ + struct UpdateMessage boot {}; + // read from misc + UPDATER_ERROR_CHECK_NOT_RETURN(ReadUpdaterMessage(MISC_FILE, boot) == true, + "ReadUpdaterMessage MISC_FILE failed!"); + // if boot.update is empty, read from command.The Misc partition may have dirty data, + // so strlen(boot.update) is not used, which can cause system exceptions. + if (boot.update[0] == '\0' && !access(COMMAND_FILE.c_str(), 0)) { + UPDATER_ERROR_CHECK_NOT_RETURN(ReadUpdaterMessage(COMMAND_FILE, boot) == true, + "ReadUpdaterMessage COMMAND_FILE failed!"); + } + STAGE(UPDATE_STAGE_OUT) << "Init Params: " << boot.update; + std::vector parseParams(argv, argv + argc); + boot.update[sizeof(boot.update) - 1] = '\0'; + std::vector parseParams1 = utils::SplitString(boot.update, "\n"); + parseParams.insert(parseParams.end(), parseParams1.begin(), parseParams1.end()); + return parseParams; +} +} // namespace updater diff --git a/test/fuzztest/ReadFstabFromFile_fuzzer/ReadFstabFromFile_fuzzer.cpp b/test/fuzztest/ReadFstabFromFile_fuzzer/ReadFstabFromFile_fuzzer.cpp index 99827d82..748a8131 100644 --- a/test/fuzztest/ReadFstabFromFile_fuzzer/ReadFstabFromFile_fuzzer.cpp +++ b/test/fuzztest/ReadFstabFromFile_fuzzer/ReadFstabFromFile_fuzzer.cpp @@ -20,7 +20,7 @@ #include #include #include -#include "fstab_api.h" +#include "fs_manager/fs_manager.h" #include "log/log.h" using namespace updater; @@ -29,7 +29,7 @@ namespace OHOS { bool FuzzReadFstabFromFile(const uint8_t* data, size_t size) { FILE *pFile; - Fstab fstab; + Fstab *fstab = NULL; const std::string fstabFile = "ReadFstabFromFile.txt"; pFile = fopen("ReadFstabFromFile.txt", "w+"); @@ -40,9 +40,9 @@ namespace OHOS { fwrite(data, 1, size, pFile); fclose(pFile); - ReadFstabFromFile(fstabFile, fstab); + fstab = ReadFstabFromFile(fstabFile.c_str(), false); remove("ReadFstabFromFile.txt"); - + ReleaseFstab(fstab); return 0; } } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 0d5d617e..5a7a54c8 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -44,6 +44,8 @@ ohos_unittest("updater_unittest") { "applypatch_test/transfer_manager_unittest.cpp", "diffpatch/bzip2_unittest.cpp", "diffpatch/diffpatch_unittest.cpp", + "flashd_test/flash_host_unittest.cpp", + "flashd_test/flash_service_unittest.cpp", "fs_manager/do_partition_unittest.cpp", "log_test/log_unittest.cpp", "misc_info_test/misc_info_unittest.cpp", @@ -91,9 +93,14 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/diffpatch/patch/blocks_patch.cpp", "//base/update/updater/services/diffpatch/patch/image_patch.cpp", "//base/update/updater/services/diffpatch/patch/update_patch.cpp", + "//base/update/updater/services/flashd/blockdevice.cpp", + "//base/update/updater/services/flashd/daemon/daemon_updater.cpp", + "//base/update/updater/services/flashd/daemon/flashd_main.cpp", + "//base/update/updater/services/flashd/flash_service.cpp", + "//base/update/updater/services/flashd/host/host_updater.cpp", + "//base/update/updater/services/flashd/partition.cpp", "//base/update/updater/services/fs_manager/cmp_partition.cpp", "//base/update/updater/services/fs_manager/do_partition.cpp", - "//base/update/updater/services/fs_manager/fstab.cpp", "//base/update/updater/services/fs_manager/mount.cpp", "//base/update/updater/services/fs_manager/partitions.cpp", "//base/update/updater/services/log/log.cpp", @@ -132,9 +139,12 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/updater_binary/update_partitions.cpp", "//base/update/updater/services/updater_binary/update_processor.cpp", "//base/update/updater/services/updater_main.cpp", + "//base/update/updater/services/updater_utils.cpp", "//base/update/updater/utils/utils.cpp", ] + include_dirs = [ + "//base/startup/init_lite/interfaces/innerkits/include", "//base/update/updater/interfaces/kits/include/", "//base/update/updater/interfaces/kits/include/package", "//base/update/updater/services/include/", @@ -154,6 +164,9 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/package/pkg_package", "//base/update/updater/services/updater_binary", "//base/update/updater/services/include/fs_manager", + "//base/update/updater/services/flashd", + "//base/update/updater/services/flashd/daemon", + "//base/update/updater/services/flashd/host", "//base/update/updater/services/fs_manager", "//base/update/updater/services/applypatch", "//base/update/updater/services/diffpatch", @@ -183,8 +196,14 @@ ohos_unittest("updater_unittest") { "//drivers/peripheral/input/hal/include", "//drivers/peripheral/input/interfaces/include", "//third_party/bounds_checking_function/include", + "//developtools/hdc_standard/src", + "//developtools/hdc_standard/src/daemon", + "//developtools/hdc_standard/src/common", + "//developtools/hdc_standard/src/host", + "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ + "//base/startup/init_lite/interfaces/innerkits/fs_manager:libfsmanager_static", "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", "//base/update/updater/interfaces/kits/misc_info:libmiscinfo", "//base/update/updater/services/applypatch:libapplypatch", @@ -195,11 +214,13 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/package:libupdaterpackage", "//base/update/updater/services/ui:libui", "//base/update/updater/utils:libutils", + "//developtools/hdc_standard:hdc_deamon_flashd", "//third_party/bounds_checking_function:libsec_static", "//third_party/bzip2:libbz2", "//third_party/cJSON:cjson_static", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", + "//third_party/libuv:uv_static", "//third_party/lz4:liblz4_static", "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", @@ -216,6 +237,9 @@ ohos_unittest("updater_unittest") { defines = [ "UPDATER_UT", "BUILD_OHOS", + "HDC_DEBUG", + "HDC_SUPPORT_FLASHD", + "HARMONY_PROJECT", ] public_configs = [ ":utest_config" ] diff --git a/test/unittest/flashd_test/flash_host_unittest.cpp b/test/unittest/flashd_test/flash_host_unittest.cpp new file mode 100755 index 00000000..c4e6d023 --- /dev/null +++ b/test/unittest/flashd_test/flash_host_unittest.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include +#include +#include + +#include "common/common.h" +#include "common/transfer.h" +#include "host_updater.h" +#include "serial_struct.h" +#include "unittest_comm.h" + +using namespace std; +using namespace Hdc; +using namespace testing::ext; +namespace { +static std::string TEST_PARTITION_NAME = "data"; +static std::string TEST_UPDATER_PACKAGE_PATH = "/data/updater/src/updater.zip"; +static std::string TEST_FLASH_IMAGE_NAME = "/data/updater/src/image/userdata.img"; + +class FLashHostUnitTest : public testing::Test { +public: + FLashHostUnitTest() {} + ~FLashHostUnitTest() {} + + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} + void SetUp() {} + void TearDown() {} + void TestBody() {} + +public: + int TestFlashHost(uint16_t command, const std::string &cmd) + { + uv_loop_t loopMain; + uv_loop_init(&loopMain); + + HTaskInfo hTaskInfo = nullptr; + std::shared_ptr task = std::make_shared(); + hTaskInfo = task.get(); + hTaskInfo->channelId = 1; + hTaskInfo->sessionId = 0; + hTaskInfo->runLoop = &loopMain; + hTaskInfo->serverOrDaemon = 0; + std::shared_ptr flashHost = std::make_shared(hTaskInfo); + flashHost->CommandDispatch(command, + const_cast(reinterpret_cast(cmd.data())), cmd.size()); + return 0; + } +}; + +HWTEST_F(FLashHostUnitTest, TestFlashHost, TestSize.Level1) +{ + FLashHostUnitTest test; + + std::string cmdParam = "update "; + cmdParam += TEST_UPDATER_PACKAGE_PATH; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_UPDATE_INIT, cmdParam)); + + cmdParam = "flash "; + cmdParam += TEST_PARTITION_NAME + " "; + cmdParam += TEST_FLASH_IMAGE_NAME; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FLASH_INIT, cmdParam)); + + cmdParam = ""; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_CHECK, cmdParam)); + + cmdParam = ""; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_BEGIN, cmdParam)); + + cmdParam = ""; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_DATA, cmdParam)); + + cmdParam = ""; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FINISH, cmdParam)); + + cmdParam = "erase -f "; + cmdParam += TEST_PARTITION_NAME; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_ERASE, cmdParam)); + + cmdParam = "format -f "; + cmdParam += TEST_PARTITION_NAME; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FORMAT, cmdParam)); + + uint32_t percentage = 30; // 30 progress + cmdParam.resize(sizeof(percentage)); + memcpy_s(cmdParam.data(), cmdParam.size(), &percentage, sizeof(percentage)); + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_PROGRESS, cmdParam)); +} +} // namespace \ No newline at end of file diff --git a/test/unittest/flashd_test/flash_service_unittest.cpp b/test/unittest/flashd_test/flash_service_unittest.cpp new file mode 100755 index 00000000..64b37920 --- /dev/null +++ b/test/unittest/flashd_test/flash_service_unittest.cpp @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include +#include +#include + +#include "common/common.h" +#include "common/transfer.h" +#include "daemon_updater.h" +#include "flash_service.h" +#include "flashd/flashd.h" +#include "serial_struct.h" +#include "unittest_comm.h" + +using namespace std; +using namespace flashd; +using namespace Hdc; +using namespace testing::ext; +namespace { +static std::string TEST_PARTITION_NAME = "data"; +static std::string TEST_UPDATER_PACKAGE_PATH = "/home/axw/develop/updater.zip"; +static std::string TEST_FLASH_IMAGE_NAME = "/home/axw/develop/image/userdata.img"; + +class FLashServiceUnitTest : public testing::Test { +public: + FLashServiceUnitTest() {} + ~FLashServiceUnitTest() {} + + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} + void SetUp() {} + void TearDown() {} + void TestBody() {} + +public: + int TestFindAllDevice() + { + std::string errorMsg; + std::shared_ptr flash = std::make_shared(errorMsg); + if (flash == nullptr) { + return 1; + } + flash->LoadSysDevice(); + return 0; + } + + int TestDoFlashPartition() + { + std::string errorMsg; + std::shared_ptr flash = std::make_shared(errorMsg); + if (flash == nullptr) { + return 1; + } + flash->DoFlashPartition(TEST_FLASH_IMAGE_NAME, TEST_PARTITION_NAME); + return 0; + } + + int TestDoErasePartition() + { + std::string errorMsg; + std::shared_ptr flash = std::make_shared(errorMsg); + if (flash == nullptr) { + return 1; + } + flash->DoErasePartition(TEST_PARTITION_NAME); + return 0; + } + + int TestDoFormatPartition() + { + std::string errorMsg; + std::shared_ptr flash = std::make_shared(errorMsg); + if (flash == nullptr) { + return 1; + } + flash->DoFormatPartition(TEST_PARTITION_NAME, "ext4"); + return 0; + } + + int TestFlashServiceDoPrepare(uint8_t type, const std::string &cmdParam) + { + std::string errorMsg; + std::shared_ptr flash = std::make_shared(errorMsg); + if (flash == nullptr) { + return 1; + } + (void)flashd::DoUpdaterPrepare(flash.get(), type, cmdParam, TEST_UPDATER_PACKAGE_PATH); + return 0; + } + + int TestFlashServiceDoFlash(uint8_t type, const std::string &cmdParam) + { + std::string errorMsg; + std::shared_ptr flash = std::make_shared(errorMsg); + if (flash == nullptr) { + return 1; + } + (void)flashd::DoUpdaterPrepare(flash.get(), type, cmdParam, TEST_UPDATER_PACKAGE_PATH); + return 0; + } + + int TestFlashServiceDoFinish(uint8_t type) + { + std::string errorMsg; + std::shared_ptr flash = std::make_shared(errorMsg); + if (flash == nullptr) { + return 1; + } + (void)flashd::DoUpdaterFinish(flash.get(), type, ""); + return 0; + } + + int TestDaemonUpdater() + { + uv_loop_t loopMain; + uv_loop_init(&loopMain); + + HTaskInfo hTaskInfo = nullptr; + std::shared_ptr task = std::make_shared(); + hTaskInfo = task.get(); + hTaskInfo->channelId = 1; + hTaskInfo->sessionId = 0; + hTaskInfo->runLoop = &loopMain; + hTaskInfo->serverOrDaemon = 1; + std::shared_ptr hdcDamon = std::make_shared(hTaskInfo); + + // cmd: hdc updater packagename + // check + HdcTransferBase::TransferConfig transferConfig {}; + transferConfig.functionName = "update"; + transferConfig.options = "update"; + std::string localPath = TEST_UPDATER_PACKAGE_PATH; + transferConfig.fileSize = 163884012; // 163884012 file size + WRITE_LOG(LOG_DEBUG, "CheckMaster %s", transferConfig.functionName.c_str()); + transferConfig.optionalName = "updater.zip"; + std::string bufString = SerialStruct::SerializeToString(transferConfig); + // 当前升级包中总的文件的大小 + const uint64_t realSize = static_cast(1024 * 1024 * 1024) * 5; + std::vector buffer(sizeof(realSize) + bufString.size()); + int ret = memcpy_s(buffer.data(), buffer.size(), &realSize, sizeof(realSize)); + EXPECT_EQ(0, ret); + ret = memcpy_s(buffer.data() + sizeof(realSize), buffer.size(), bufString.c_str(), bufString.size()); + EXPECT_EQ(0, ret); + hdcDamon->CommandDispatch(CMD_UPDATER_CHECK, buffer.data(), buffer.size()); + + // begin + hdcDamon->CommandDispatch(CMD_UPDATER_BEGIN, NULL, 0); + + // data 写数据部分 + const uint32_t dataSize = 1024; // 1024 data size + HdcTransferBase::TransferPayload payloadHead {}; + payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; + payloadHead.uncompressSize = dataSize; + payloadHead.compressSize = dataSize; + payloadHead.index = 0; + std::string bufData = SerialStruct::SerializeToString(payloadHead); + hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); + + payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; + payloadHead.uncompressSize = dataSize; + payloadHead.compressSize = dataSize; + payloadHead.index = 1; + bufData = SerialStruct::SerializeToString(payloadHead); + hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); + // end + hdcDamon->DoTransferFinish(); + return 0; + } + + int TestHdcDaemonFlash() + { + uv_loop_t loopMain; + uv_loop_init(&loopMain); + + HTaskInfo hTaskInfo = nullptr; + std::shared_ptr task = std::make_shared(); + hTaskInfo = task.get(); + hTaskInfo->channelId = 2; // 2 channel id + hTaskInfo->sessionId = 0; + hTaskInfo->runLoop = &loopMain; + hTaskInfo->serverOrDaemon = 1; + std::shared_ptr hdcDamon = std::make_shared(hTaskInfo); + + // cmd: hdc flash partition packagename + // check + HdcTransferBase::TransferConfig transferConfig {}; + transferConfig.functionName = "flash"; + transferConfig.options = TEST_PARTITION_NAME; + transferConfig.options += " "; + transferConfig.options += TEST_FLASH_IMAGE_NAME; + std::string localPath = TEST_FLASH_IMAGE_NAME; + transferConfig.fileSize = 1468006400; // 1468006400 file size + WRITE_LOG(LOG_DEBUG, "CheckMaster %s", transferConfig.functionName.c_str()); + transferConfig.optionalName = "userdata.img"; + std::string bufString = SerialStruct::SerializeToString(transferConfig); + // 当前升级包中总的文件的大小 + const uint64_t realSize = static_cast(1024 * 1024 * 1024) * 5; + std::vector buffer(sizeof(realSize) + bufString.size()); + int ret = memcpy_s(buffer.data(), buffer.size(), &realSize, sizeof(realSize)); + EXPECT_EQ(0, ret); + ret = memcpy_s(buffer.data() + sizeof(realSize), buffer.size(), bufString.c_str(), bufString.size()); + EXPECT_EQ(0, ret); + hdcDamon->CommandDispatch(CMD_UPDATER_CHECK, buffer.data(), buffer.size()); + + // begin + hdcDamon->CommandDispatch(CMD_UPDATER_BEGIN, NULL, 0); + + // data 写数据部分 + const uint32_t dataSize = 1024; // 1024 data size + HdcTransferBase::TransferPayload payloadHead {}; + payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; + payloadHead.uncompressSize = dataSize; + payloadHead.compressSize = dataSize; + payloadHead.index = 0; + std::string bufData = SerialStruct::SerializeToString(payloadHead); + hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); + + payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; + payloadHead.uncompressSize = dataSize; + payloadHead.compressSize = dataSize; + payloadHead.index = 1; + bufData = SerialStruct::SerializeToString(payloadHead); + hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); + // end + hdcDamon->DoTransferFinish(); + return 0; + } + + int TestHdcDaemonErase() + { + uv_loop_t loopMain; + uv_loop_init(&loopMain); + + HTaskInfo hTaskInfo = nullptr; + std::shared_ptr task = std::make_shared(); + hTaskInfo = task.get(); + hTaskInfo->channelId = 2; // 2 channel id + hTaskInfo->sessionId = 0; + hTaskInfo->runLoop = &loopMain; + hTaskInfo->serverOrDaemon = 1; + std::shared_ptr hdcDamon = std::make_shared(hTaskInfo); + + // cmd: hdc erase partition + // check + HdcTransferBase::TransferConfig transferConfig {}; + transferConfig.functionName = "erase"; + transferConfig.options = "erase -f "; + transferConfig.options += TEST_PARTITION_NAME; + std::string bufString = SerialStruct::SerializeToString(transferConfig); + hdcDamon->CommandDispatch(CMD_UPDATER_ERASE, reinterpret_cast(bufString.data()), bufString.size()); + return 0; + } + + int TestHdcDaemonFormat() + { + uv_loop_t loopMain; + uv_loop_init(&loopMain); + + HTaskInfo hTaskInfo = nullptr; + std::shared_ptr task = std::make_shared(); + hTaskInfo = task.get(); + hTaskInfo->channelId = 2; // 2 channel id + hTaskInfo->sessionId = 0; + hTaskInfo->runLoop = &loopMain; + hTaskInfo->serverOrDaemon = 1; + std::shared_ptr hdcDamon = std::make_shared(hTaskInfo); + + // cmd: hdc format partition + // check + HdcTransferBase::TransferConfig transferConfig {}; + transferConfig.functionName = "format"; + transferConfig.options = "format -f "; + transferConfig.options += TEST_PARTITION_NAME; + std::string bufString = SerialStruct::SerializeToString(transferConfig); + hdcDamon->CommandDispatch(CMD_UPDATER_ERASE, reinterpret_cast(bufString.data()), bufString.size()); + return 0; + } +}; + +HWTEST_F(FLashServiceUnitTest, FLashServiceUnitTest, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestFindAllDevice()); +} + +HWTEST_F(FLashServiceUnitTest, TestDaemonUpdater, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestDaemonUpdater()); +} + +HWTEST_F(FLashServiceUnitTest, TestHdcDaemonFlash, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestHdcDaemonFlash()); +} + +HWTEST_F(FLashServiceUnitTest, TestHdcDaemonErase, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestHdcDaemonErase()); +} + +HWTEST_F(FLashServiceUnitTest, TestHdcDaemonFormat, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestHdcDaemonFormat()); +} + +HWTEST_F(FLashServiceUnitTest, TestFindAllDevice, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestFindAllDevice()); +} + +HWTEST_F(FLashServiceUnitTest, TestDoFlashPartition, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestDoFlashPartition()); +} + +HWTEST_F(FLashServiceUnitTest, TestDoFormatPartition, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestDoFormatPartition()); +} + +HWTEST_F(FLashServiceUnitTest, TestDoErasePartition, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestDoErasePartition()); +} + +HWTEST_F(FLashServiceUnitTest, TestFlashServiceDoPrepare, TestSize.Level1) +{ + FLashServiceUnitTest test; + std::string cmdParam = "update "; + EXPECT_EQ(0, test.TestFlashServiceDoPrepare(flashd::UPDATEMOD_UPDATE, cmdParam)); + + cmdParam = "flash "; + cmdParam += TEST_PARTITION_NAME + " "; + cmdParam += TEST_FLASH_IMAGE_NAME; + EXPECT_EQ(0, test.TestFlashServiceDoPrepare(flashd::UPDATEMOD_FLASH, cmdParam)); + + cmdParam = "erase -f"; + cmdParam += TEST_PARTITION_NAME + " "; + EXPECT_EQ(0, test.TestFlashServiceDoPrepare(flashd::UPDATEMOD_ERASE, cmdParam)); + + cmdParam = "format -f "; + cmdParam += TEST_PARTITION_NAME + " "; + EXPECT_EQ(0, test.TestFlashServiceDoPrepare(flashd::UPDATEMOD_FORMAT, cmdParam)); + + EXPECT_EQ(0, test.TestFlashServiceDoPrepare(flashd::UPDATEMOD_MAX, cmdParam)); +} + +HWTEST_F(FLashServiceUnitTest, TestFlashServiceDoFlash, TestSize.Level1) +{ + FLashServiceUnitTest test; + std::string cmdParam = "update "; + EXPECT_EQ(0, test.TestFlashServiceDoFlash(flashd::UPDATEMOD_UPDATE, cmdParam)); + + cmdParam = "flash "; + cmdParam += TEST_PARTITION_NAME + " "; + cmdParam += TEST_FLASH_IMAGE_NAME; + EXPECT_EQ(0, test.TestFlashServiceDoFlash(flashd::UPDATEMOD_FLASH, cmdParam)); + + cmdParam = "erase -f "; + cmdParam += TEST_PARTITION_NAME + " "; + EXPECT_EQ(0, test.TestFlashServiceDoFlash(flashd::UPDATEMOD_ERASE, cmdParam)); + + cmdParam = "format -f ext4 "; + cmdParam += TEST_PARTITION_NAME + " "; + EXPECT_EQ(0, test.TestFlashServiceDoFlash(flashd::UPDATEMOD_FORMAT, cmdParam)); + + cmdParam = "format -f f2fs "; + cmdParam += TEST_PARTITION_NAME + " "; + EXPECT_EQ(0, test.TestFlashServiceDoFlash(flashd::UPDATEMOD_FORMAT, cmdParam)); + + EXPECT_EQ(0, test.TestFlashServiceDoFlash(flashd::UPDATEMOD_MAX, cmdParam)); +} + +HWTEST_F(FLashServiceUnitTest, TestFlashServiceDoFinish, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestFlashServiceDoFinish(flashd::UPDATEMOD_UPDATE)); + EXPECT_EQ(0, test.TestFlashServiceDoFinish(flashd::UPDATEMOD_FLASH)); + EXPECT_EQ(0, test.TestFlashServiceDoFinish(flashd::UPDATEMOD_MAX)); +} + +HWTEST_F(FLashServiceUnitTest, TestFlashdMain, TestSize.Level1) +{ + const char* argv1[] = {"TestFlashdMain", "-t"}; + flashd_main(sizeof(argv1) / sizeof(char*), const_cast(argv1)); + const char *argv2[] = {"TestFlashdMain", "-u", " -l5"}; + flashd_main(sizeof(argv2)/sizeof(char*), const_cast(argv2)); +} +} // namespace \ No newline at end of file diff --git a/test/unittest/mount_test/fstabapi_unittest.cpp b/test/unittest/mount_test/fstabapi_unittest.cpp index 6605ccb8..e772ece4 100755 --- a/test/unittest/mount_test/fstabapi_unittest.cpp +++ b/test/unittest/mount_test/fstabapi_unittest.cpp @@ -23,9 +23,7 @@ #include #include #include -#include -#include "fs_manager/fstab.h" -#include "fs_manager/fstab_api.h" +#include "fs_manager/fs_manager.h" #include "fs_manager/mount.h" #include "log/log.h" #include "utils.h" @@ -55,95 +53,98 @@ void FstabApiUnitTest::TearDownTestCase(void) {} HWTEST_F(FstabApiUnitTest, ReadFstabFromFile_unitest, TestSize.Level1) { - Fstab fstab; + Fstab *fstab = nullptr; const std::string fstabFile1 = "/data/fstab.updater1"; - bool ret = ReadFstabFromFile(fstabFile1, fstab); - EXPECT_FALSE(ret); + fstab = ReadFstabFromFile(fstabFile1.c_str(), false); + EXPECT_EQ(fstab, nullptr); const std::string fstabFile2 = "/data/updater/mount_unitest/ReadFstabFromFile1.fstable"; - ret = ReadFstabFromFile(fstabFile2, fstab); - EXPECT_FALSE(ret); + fstab = ReadFstabFromFile(fstabFile2.c_str(), false); + EXPECT_EQ(fstab, nullptr); const std::string fstabFile3 = "/data/updater/mount_unitest/ReadFstabFromFile2.fstable"; - ret = ReadFstabFromFile(fstabFile3, fstab); - EXPECT_FALSE(ret); + fstab = ReadFstabFromFile(fstabFile3.c_str(), false); + EXPECT_EQ(fstab, nullptr); const std::string fstabFile4 = "/data/updater/mount_unitest/ReadFstabFromFile3.fstable"; - ret = ReadFstabFromFile(fstabFile4, fstab); - EXPECT_FALSE(ret); + fstab = ReadFstabFromFile(fstabFile4.c_str(), false); + EXPECT_EQ(fstab, nullptr); const std::string fstabFile5 = "/data/updater/mount_unitest/ReadFstabFromFile4.fstable"; - ret = ReadFstabFromFile(fstabFile5, fstab); - EXPECT_FALSE(ret); + fstab = ReadFstabFromFile(fstabFile5.c_str(), false); + EXPECT_EQ(fstab, nullptr); const std::string fstabFile6 = "/data/updater/mount_unitest/ReadFstabFromFile5.fstable"; - ret = ReadFstabFromFile(fstabFile6, fstab); - EXPECT_TRUE(ret); + fstab = ReadFstabFromFile(fstabFile6.c_str(), false); + EXPECT_NE(fstab, nullptr); + ReleaseFstab(fstab); } HWTEST_F(FstabApiUnitTest, FindFstabItemForPath_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/FindFstabItemForPath1.fstable"; - Fstab fstab1; - ReadFstabFromFile(fstabFile1, fstab1); - struct FstabItem* item = nullptr; + Fstab *fstab = nullptr; + fstab = ReadFstabFromFile(fstabFile1.c_str(), false); + ASSERT_NE(fstab, nullptr); + FstabItem* item = nullptr; const std::string path1 = ""; - item = FindFstabItemForPath(fstab1, path1); + item = FindFstabItemForPath(*fstab, path1.c_str()); if (item == nullptr) { SUCCEED(); } const std::string path2 = "/data"; - item = FindFstabItemForPath(fstab1, path2); + item = FindFstabItemForPath(*fstab, path2.c_str()); if (item != nullptr) { SUCCEED(); } const std::string path3 = "/data2"; - item = FindFstabItemForPath(fstab1, path3); + item = FindFstabItemForPath(*fstab, path3.c_str()); if (item == nullptr) { SUCCEED(); } const std::string path4 = "/data2/test"; - item = FindFstabItemForPath(fstab1, path4); + item = FindFstabItemForPath(*fstab, path4.c_str()); if (item != nullptr) { SUCCEED(); } + ReleaseFstab(fstab); + fstab = nullptr; } HWTEST_F(FstabApiUnitTest, FindFstabItemForMountPoint_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/FindFstabItemForMountPoint1.fstable"; - Fstab fstab1; - ReadFstabFromFile(fstabFile1, fstab1); - struct FstabItem* item = nullptr; + Fstab *fstab = nullptr; + fstab = ReadFstabFromFile(fstabFile1.c_str(), false); + ASSERT_NE(fstab, nullptr); + FstabItem* item = nullptr; const std::string mp1 = "/data"; const std::string mp2 = "/data2"; - item = FindFstabItemForMountPoint(fstab1, mp2); + item = FindFstabItemForMountPoint(*fstab, mp2.c_str()); if (item == nullptr) { SUCCEED(); } const std::string mp3 = "/data"; - item = FindFstabItemForMountPoint(fstab1, mp3); + item = FindFstabItemForMountPoint(*fstab, mp3.c_str()); if (item != nullptr) { SUCCEED(); } + ReleaseFstab(fstab); + fstab = nullptr; } HWTEST_F(FstabApiUnitTest, GetMountFlags_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/GetMountFlags1.fstable"; - int fd = open(fstabFile1.c_str(), O_RDONLY); - if (fd < 0) { - cout << "fstabFile open failed, fd = " << fd << endl; - FAIL(); - return; - } else { - close(fd); - } - Fstab fstab1; - ReadFstabFromFile(fstabFile1, fstab1); + Fstab *fstab = nullptr; + fstab = ReadFstabFromFile(fstabFile1.c_str(), false); + ASSERT_NE(fstab, nullptr); struct FstabItem* item = nullptr; const std::string mp = "/hos"; - item = FindFstabItemForMountPoint(fstab1, mp); + item = FindFstabItemForMountPoint(*fstab, mp.c_str()); if (item == nullptr) { SUCCEED(); } - std::string fsSpecificOptions; - unsigned long flags = GetMountFlags(item->mountOptions, fsSpecificOptions); + const int bufferSize = 512; + char fsSpecificOptions[bufferSize] = {0}; + unsigned long flags = GetMountFlags(item->mountOptions, fsSpecificOptions, bufferSize); EXPECT_EQ(flags, static_cast(MS_NOSUID | MS_NODEV | MS_NOATIME)); + ReleaseFstab(fstab); + fstab = nullptr; } } // namespace updater_ut diff --git a/test/unittest/mount_test/mount_unittest.cpp b/test/unittest/mount_test/mount_unittest.cpp index 80f80b8d..e008ecdb 100755 --- a/test/unittest/mount_test/mount_unittest.cpp +++ b/test/unittest/mount_test/mount_unittest.cpp @@ -25,8 +25,7 @@ #include #include #include -#include "fs_manager/fstab.h" -#include "fs_manager/fstab_api.h" +#include "fs_manager/fs_manager.h" #include "fs_manager/mount.h" #include "log/log.h" #include "utils.h" @@ -129,29 +128,6 @@ HWTEST_F(MountUnitTest, GetMountStatusForPath_unitest, TestSize.Level1) EXPECT_EQ(ret, MountStatus::MOUNT_UMOUNTED); } -HWTEST_F(MountUnitTest, GetItemForMountPoint_unitest, TestSize.Level1) -{ - const std::string fstabFile1 = "/data/updater/mount_unitest/GetItemForMountPoint1.fstable"; - LoadSpecificFstab(fstabFile1); - const std::string mountPoint1 = "/data"; - struct FstabItem * item = GetItemForMountPoint(mountPoint1); - if (item == nullptr) { - SUCCEED(); - } - const std::string fstabFile2 = "/data/updater/mount_unitest/GetItemForMountPoint2.fstable"; - LoadSpecificFstab(fstabFile2); - const std::string mountPoint2 = "/data2"; - item = GetItemForMountPoint(mountPoint2); - if (item == nullptr) { - SUCCEED(); - } - const std::string mountPoint3 = "/data"; - item = GetItemForMountPoint(mountPoint3); - if (item != nullptr) { - SUCCEED(); - } -} - HWTEST_F(MountUnitTest, SetupPartitions_unitest, TestSize.Level1) { const std::string fstabFile1 = "/data/updater/mount_unitest/SetupPartitions1.fstable"; diff --git a/test/unittest/package/pkg_manager_unittest.cpp b/test/unittest/package/pkg_manager_unittest.cpp index ec795918..b7143e9f 100755 --- a/test/unittest/package/pkg_manager_unittest.cpp +++ b/test/unittest/package/pkg_manager_unittest.cpp @@ -52,7 +52,8 @@ constexpr int32_t ZIP_MAX_LEVEL = 9; class TestPkgStream : public PkgStreamImpl { public: - explicit TestPkgStream(std::string fileName) : PkgStreamImpl(fileName) {} + explicit TestPkgStream(PkgManager::PkgManagerPtr pkgManager, std::string fileName) + : PkgStreamImpl(pkgManager, fileName) {} virtual ~TestPkgStream() {} int32_t Read(const PkgBuffer &buff, size_t start, size_t size, size_t &readLen) override @@ -229,7 +230,7 @@ public: int TestPkgStreamImpl() { std::string path = TEST_PATH_TO + testCombinePkgName; - std::unique_ptr stream = std::make_unique(path); + std::unique_ptr stream = std::make_unique(pkgManager_, path); EXPECT_NE(stream, nullptr); constexpr size_t buffSize = 10; uint8_t buff[buffSize]; @@ -342,7 +343,7 @@ public: { std::string packagePath = TEST_PATH_TO; packagePath += testPackageName; - auto stream = std::make_unique(testPackageName, nullptr, 0); + auto stream = std::make_unique(pkgManager_, testPackageName, nullptr, 0); size_t start = 0; size_t readLen = 0; size_t bufferSize = 10; diff --git a/test/unittest/package/pkg_package_unittest.cpp b/test/unittest/package/pkg_package_unittest.cpp index 56272e3b..2880e5cd 100755 --- a/test/unittest/package/pkg_package_unittest.cpp +++ b/test/unittest/package/pkg_package_unittest.cpp @@ -41,7 +41,8 @@ constexpr uint32_t END_CENTRAL_SIGNATURE = 0x06054b50; class TestFile : public PkgFile { public: - explicit TestFile(PkgStreamPtr stream) : PkgFile(stream, PKG_TYPE_MAX) {} + explicit TestFile(PkgManager::PkgManagerPtr pkgManager, PkgStreamPtr stream) + : PkgFile(pkgManager, stream, PKG_TYPE_MAX) {} virtual ~TestFile() {} @@ -78,7 +79,7 @@ public: std::string packagePath = TEST_PATH_TO; packagePath += testPackageName; int ret = pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); - auto file = std::make_unique(PkgStreamImpl::ConvertPkgStream(stream)); + auto file = std::make_unique(pkgManager_, PkgStreamImpl::ConvertPkgStream(stream)); EXPECT_NE(file, nullptr); constexpr uint32_t lz4NodeId = 100; auto entry = std::make_unique(file.get(), lz4NodeId); @@ -102,7 +103,8 @@ public: packagePath += testPackageName; int ret = pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); FileInfo fileInfo; - std::unique_ptr file = std::make_unique(PkgStreamImpl::ConvertPkgStream(stream)); + std::unique_ptr file = std::make_unique(pkgManager_, + PkgStreamImpl::ConvertPkgStream(stream)); EXPECT_NE(file, nullptr); ret = file->AddEntry(&fileInfo, PkgStreamImpl::ConvertPkgStream(stream)); EXPECT_EQ(ret, 0); @@ -122,7 +124,8 @@ public: packagePath += testPackageName; pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); EXPECT_NE(stream, nullptr); - std::unique_ptr file = std::make_unique(PkgStreamImpl::ConvertPkgStream(stream)); + std::unique_ptr file = std::make_unique(pkgManager_, + PkgStreamImpl::ConvertPkgStream(stream)); EXPECT_NE(file, nullptr); std::unique_ptr entry = std::make_unique(file.get(), zipNodeId); EXPECT_NE(entry, nullptr); @@ -154,7 +157,7 @@ public: centralDir->internalAttr = 0; centralDir->externalAttr = 0; centralDir->localHeaderOffset = 0; - int ret = memcpy_s(buff.data() + sizeof(CentralDirEntry), name.length(), name.c_str(), name.length()); + int ret = memcpy_s(buff.data() + sizeof(CentralDirEntry), name.length(), name.c_str(), name.length()); EXPECT_EQ(ret, 0); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length(), 1); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetHalfWord, offset4Words); @@ -215,7 +218,8 @@ public: sizeof(endDir), &endDir, sizeof(endDir)), 0); - std::unique_ptr zipFile = std::make_unique(PkgStreamImpl::ConvertPkgStream(stream)); + std::unique_ptr zipFile = std::make_unique(pkgManager_, + PkgStreamImpl::ConvertPkgStream(stream)); EXPECT_NE(zipFile, nullptr); std::vector components; int ret = zipFile->LoadPackage(components); diff --git a/test/unittest/updater_main_test/updater_main_unittest.cpp b/test/unittest/updater_main_test/updater_main_unittest.cpp index 5a696c0a..a3e33c78 100755 --- a/test/unittest/updater_main_test/updater_main_unittest.cpp +++ b/test/unittest/updater_main_test/updater_main_unittest.cpp @@ -24,6 +24,7 @@ #include "securec.h" #include "updater_main.h" #include "updater_ui.h" +#include "updater/updater.h" #include "utils.h" using namespace updater; @@ -131,10 +132,12 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_004, TestSize.Level1) bool ret = WriteUpdaterMessage(MISC_FILE, boot); EXPECT_EQ(ret, true); - int lRet = 0; - int argc = 1; char **argv = new char*[MAX_ARG_SIZE]; argv[0] = new char[10]; + EXPECT_EQ(strncpy_s(argv[0], MAX_ARG_SIZE, "./main", MAX_ARG_SIZE), 0); + int argc = 1; + int lRet = UpdaterMain(argc, argv); + EXPECT_EQ(lRet, 0); EXPECT_EQ(memset_s(boot.update, sizeof(boot.update), 0, sizeof(boot.update)), 0); const std::string command3 = "--user_wipe_data"; diff --git a/test/unittest/updater_test/updater_unittest.cpp b/test/unittest/updater_test/updater_unittest.cpp index 60dced83..c11ffe0c 100755 --- a/test/unittest/updater_test/updater_unittest.cpp +++ b/test/unittest/updater_test/updater_unittest.cpp @@ -112,4 +112,11 @@ HWTEST_F(UpdaterUnitTest, updater_GetUpdatePackageInfo, TestSize.Level1) PkgManager::ReleasePackageInstance(pkgManager); EXPECT_EQ(ret, static_cast(PKG_SUCCESS)); } + +HWTEST_F(UpdaterUnitTest, updater_UpdateSdcard, TestSize.Level1) +{ + UpdaterStatus status; + status = UpdaterFromSdcard(); + EXPECT_EQ(status, UPDATE_SUCCESS); +} } // namespace updater_ut diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 07028461..2adba505 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -21,6 +21,7 @@ ohos_static_library("libutils") { "//base/update/updater/interfaces/kits/include/", "//base/update/updater/services/include/", "//third_party/bounds_checking_function/include", + "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ "//third_party/bounds_checking_function:libsec_static" ] @@ -53,6 +54,7 @@ ohos_executable("write_updater") { "//base/update/updater/interfaces/kits/include/", "//base/update/updater/services/include/", "//third_party/bounds_checking_function/include", + "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ diff --git a/utils/include/utils.h b/utils/include/utils.h index 9540675a..62366084 100644 --- a/utils/include/utils.h +++ b/utils/include/utils.h @@ -48,15 +48,13 @@ int64_t GetFilesFromDirectory(const std::string &path, std::vector std::vector SplitString(const std::string &str, const std::string del = " \t"); std::string Trim(const std::string &str); std::string ConvertSha256Hex(const uint8_t* shaDigest, size_t length); -void DoReboot(const std::string& rebootTarget); +void DoReboot(const std::string& rebootTarget, const std::string& extData = ""); std::string GetCertName(); bool WriteFully(int fd, const void *data, size_t size); bool ReadFully(int fd, void* data, size_t size); bool ReadFileToString(int fd, std::string &content); bool WriteStringToFile(int fd, const std::string& content); std::string GetLocalBoardId(); -bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog); -void CompressLogs(const std::string &name); } // utils } // updater #endif // UPDATER_UTILS_H diff --git a/utils/updater_reboot.cpp b/utils/updater_reboot.cpp index 87546f3b..7c57ff61 100644 --- a/utils/updater_reboot.cpp +++ b/utils/updater_reboot.cpp @@ -32,8 +32,12 @@ int main(int argc, char **argv) std::string updaterStr = "updater"; if (!memcmp(argv[1], updaterStr.c_str(), updaterStr.length())) { updater::utils::DoReboot(argv[1]); + } else if (strcmp(argv[1], "flash") == 0) { + updater::utils::DoReboot(argv[1]); + } else if (strncmp(argv[1], "flash:", strlen("flash:")) == 0) { + updater::utils::DoReboot("flash", argv[1] + strlen("flash:")); } else { - updater::LOG(updater::INFO) << "param must be updater!"; + updater::LOG(updater::INFO) << "param must be updater/flash!"; } } return 0; diff --git a/utils/utils.cpp b/utils/utils.cpp index 84b21d20..4f2ead20 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -39,8 +39,6 @@ using namespace hpackage; namespace utils { constexpr uint32_t MAX_PATH_LEN = 256; constexpr uint8_t SHIFT_RIGHT_FOUR_BITS = 4; -constexpr int USER_ROOT_AUTHORITY = 0; -constexpr int GROUP_SYS_AUTHORITY = 1000; int32_t DeleteFile(const std::string& filename) { UPDATER_ERROR_CHECK (!filename.empty(), "Invalid filename", return -1); @@ -159,33 +157,42 @@ std::string ConvertSha256Hex(const uint8_t* shaDigest, size_t length) return haxSha256; } -void DoReboot(const std::string& rebootTarget) +void DoReboot(const std::string& rebootTarget, const std::string &extData) { LOG(INFO) << ", rebootTarget: " << rebootTarget; + static const int32_t maxCommandSize = 16; LoadFstab(); auto miscBlockDevice = GetBlockDeviceByMountPoint("/misc"); struct UpdateMessage msg; - if (rebootTarget == "updater") { - std::string command = "boot_updater"; - bool ret = ReadUpdaterMessage(miscBlockDevice, msg); - UPDATER_ERROR_CHECK(ret == true, "DoReboot read misc failed", return); - if (strcmp(msg.command, command.c_str()) != 0) { - UPDATER_ERROR_CHECK(memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE) == 0, - "Failed to clear update message", return); - UPDATER_ERROR_CHECK(!memcpy_s(msg.command, MAX_COMMAND_SIZE - 1, command.c_str(), command.size()), - "Memcpy failed", return); - } - ret = WriteUpdaterMessage(miscBlockDevice, msg); - if (ret != true) { - LOG(INFO) << "DoReboot: WriteUpdaterMessage boot_updater error"; + if (rebootTarget.empty()) { + UPDATER_ERROR_CHECK(!memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE), "Memset_s failed", return); + if (WriteUpdaterMessage(miscBlockDevice, msg) != true) { + LOG(INFO) << "DoReboot: WriteUpdaterMessage empty error"; return; } sync(); } else { - UPDATER_ERROR_CHECK(!memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE), "Memset_s failed", return); - bool ret = WriteUpdaterMessage(miscBlockDevice, msg); - if (ret != true) { - LOG(INFO) << "DoReboot: WriteUpdaterMessage empty error"; + int result = 0; + bool ret = ReadUpdaterMessage(miscBlockDevice, msg); + UPDATER_ERROR_CHECK(ret == true, "DoReboot read misc failed", return); + if (rebootTarget == "updater" && strcmp(msg.command, "boot_updater") != 0) { + result = strcpy_s(msg.command, maxCommandSize, "boot_updater"); + msg.command[maxCommandSize] = 0; + } else if (rebootTarget == "flash" && strcmp(msg.command, "flash") != 0) { + result = strcpy_s(msg.command, maxCommandSize, "boot_flash"); + msg.command[maxCommandSize] = 0; + } else if (rebootTarget == "bootloader" && strcmp(msg.command, "boot_loader") != 0) { + result = strcpy_s(msg.command, maxCommandSize, "boot_loader"); + msg.command[maxCommandSize] = 0; + } + UPDATER_ERROR_CHECK(result == 0, "strcpy failed", return); + if (!extData.empty()) { + result = strcpy_s(msg.update, MAX_UPDATE_SIZE - 1, extData.c_str()); + UPDATER_ERROR_CHECK(result == 0, "Failed to copy update", return); + msg.update[MAX_UPDATE_SIZE - 1] = 0; + } + if (WriteUpdaterMessage(miscBlockDevice, msg) != true) { + LOG(INFO) << "DoReboot: WriteUpdaterMessage boot_updater error"; return; } sync(); @@ -278,74 +285,5 @@ std::string GetLocalBoardId() { return "HI3516"; } - -void CompressLogs(const std::string &name) -{ - PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); - UPDATER_ERROR_CHECK(pkgManager != nullptr, "pkgManager is nullptr", return); - std::vector> files; - // Build the zip file to be packaged - std::vector testFileNames; - std::string realName = name.substr(name.find_last_of("/") + 1); - testFileNames.push_back(realName); - for (auto name : testFileNames) { - ZipFileInfo file; - file.fileInfo.identity = name; - file.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP; - file.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC; - std::string fileName = "/data/updater/log/" + name; - files.push_back(std::pair(fileName, file)); - } - - PkgInfo pkgInfo; - pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; - pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; - pkgInfo.pkgType = PKG_PACK_TYPE_ZIP; - - char realTime[MAX_TIME_SIZE] = {0}; - auto sysTime = std::chrono::system_clock::now(); - auto currentTime = std::chrono::system_clock::to_time_t(sysTime); - struct tm *localTime = std::localtime(¤tTime); - if (localTime != nullptr) { - std::strftime(realTime, sizeof(realTime), "%H_%M_%S", localTime); - } - char pkgName[MAX_LOG_NAME_SIZE]; - UPDATER_CHECK_ONLY_RETURN(snprintf_s(pkgName, MAX_LOG_NAME_SIZE, MAX_LOG_NAME_SIZE - 1, - "/data/updater/log/%s_%s.zip", realName.c_str(), realTime) != -1, return); - int32_t ret = pkgManager->CreatePackage(pkgName, GetCertName(), &pkgInfo, files); - UPDATER_CHECK_ONLY_RETURN(ret != 0, return); - UPDATER_CHECK_ONLY_RETURN(DeleteFile(name) == 0, return); -} - -bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog) -{ - UPDATER_WARING_CHECK(MountForPath(UPDATER_LOG_DIR) == 0, "MountForPath /data/log failed!", return false); - if (access(UPDATER_LOG_DIR.c_str(), 0) != 0) { - UPDATER_ERROR_CHECK(!MkdirRecursive(UPDATER_LOG_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH), - "MkdirRecursive error!", return false); - UPDATER_ERROR_CHECK(chown(UPDATER_PATH.c_str(), USER_ROOT_AUTHORITY, GROUP_SYS_AUTHORITY) == 0, - "Chown failed!", return false); - UPDATER_ERROR_CHECK(chmod(UPDATER_PATH.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0, - "Chmod failed!", return false); - } - - FILE* dFp = fopen(dLog.c_str(), "ab+"); - UPDATER_ERROR_CHECK(dFp != nullptr, "open log failed", return false); - - FILE* sFp = fopen(sLog.c_str(), "r"); - UPDATER_ERROR_CHECK(sFp != nullptr, "open log failed", fclose(dFp); return false); - - char buf[MAX_LOG_BUF_SIZE]; - size_t bytes; - while ((bytes = fread(buf, 1, sizeof(buf), sFp)) != 0) { - fwrite(buf, 1, bytes, dFp); - } - fseek(dFp, 0, SEEK_END); - UPDATER_INFO_CHECK(ftell(dFp) < MAX_LOG_SIZE, "log size greater than 5M!", CompressLogs(dLog)); - sync(); - fclose(sFp); - fclose(dFp); - return true; -} } // utils } // namespace updater -- Gitee From 9cbb4101725713daecad2740c32c7977ada7d2a0 Mon Sep 17 00:00:00 2001 From: "411148299@qq.com" <411148299@qq.com> Date: Mon, 18 Oct 2021 16:20:56 +0800 Subject: [PATCH 31/94] fix code style Signed-off-by: 411148299@qq.com <411148299@qq.com> --- ohos.build | 1 - 1 file changed, 1 deletion(-) diff --git a/ohos.build b/ohos.build index 341a12ee..2a46178a 100644 --- a/ohos.build +++ b/ohos.build @@ -32,7 +32,6 @@ ], "test_list": [ "//base/update/updater:unittest", - "//base/update/updateservice:unittest" ] } } -- Gitee From 17e79e7387155ee9377f63550ee3f771375790a9 Mon Sep 17 00:00:00 2001 From: "411148299@qq.com" <411148299@qq.com> Date: Mon, 18 Oct 2021 16:25:37 +0800 Subject: [PATCH 32/94] fix code style Signed-off-by: 411148299@qq.com <411148299@qq.com> --- ohos.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ohos.build b/ohos.build index 2a46178a..591fd5bd 100644 --- a/ohos.build +++ b/ohos.build @@ -31,7 +31,7 @@ "//base/update/updater/services/flashd:updater_flashd" ], "test_list": [ - "//base/update/updater:unittest", + "//base/update/updater:unittest" ] } } -- Gitee From 0205a362b6409115597d0506e121732b06c118d9 Mon Sep 17 00:00:00 2001 From: "411148299@qq.com" <411148299@qq.com> Date: Tue, 19 Oct 2021 11:16:39 +0800 Subject: [PATCH 33/94] fix code style Signed-off-by: 411148299@qq.com <411148299@qq.com> --- ohos.build | 3 +-- services/BUILD.gn | 1 - services/main.cpp | 5 ----- test/unittest/BUILD.gn | 21 --------------------- 4 files changed, 1 insertion(+), 29 deletions(-) diff --git a/ohos.build b/ohos.build index 591fd5bd..9ef224ed 100644 --- a/ohos.build +++ b/ohos.build @@ -27,8 +27,7 @@ "//base/update/updateservice/interfaces/innerkits/engine:updateservicekits", "//base/update/updater/services/ui:libui", "//third_party/libdrm:libdrm", - "//third_party/e2fsprogs:e2fsprogs", - "//base/update/updater/services/flashd:updater_flashd" + "//third_party/e2fsprogs:e2fsprogs" ], "test_list": [ "//base/update/updater:unittest" diff --git a/services/BUILD.gn b/services/BUILD.gn index 945f511d..a52c4d29 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -95,7 +95,6 @@ ohos_executable("updater") { "//base/update/updater/interfaces/kits/packages:libpackageExt", "//base/update/updater/services/applypatch:libapplypatch", "//base/update/updater/services/diffpatch/patch:libpatch", - "//base/update/updater/services/flashd:libflashd", "//base/update/updater/services/fs_manager:libfsmanager", "//base/update/updater/services/log:libupdaterlog", "//base/update/updater/services/package:libupdaterpackage", diff --git a/services/main.cpp b/services/main.cpp index e0173eef..e492a280 100644 --- a/services/main.cpp +++ b/services/main.cpp @@ -12,7 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "flashd/flashd.h" #include "fs_manager/mount.h" #include "log/log.h" #include "misc_info/misc_info.h" @@ -37,7 +36,6 @@ int main(int argc, char **argv) printf("ReadUpdaterMessage COMMAND_FILE failed!\n"); } } - const int flashBootLength = 10; bool useFlash = memcmp(boot.command, "boot_flash", flashBootLength) == 0; InitUpdaterLogger(useFlash ? "FLASHD" : "UPDATER", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); @@ -46,8 +44,5 @@ int main(int argc, char **argv) STAGE(UPDATE_STAGE_OUT) << "Init Params: " << boot.update; LOG(INFO) << "boot.command " << boot.command; LOG(INFO) << "boot.update " << boot.update; - if (useFlash) { - return flashd::flashd_main(argc, argv); - } return updater::UpdaterMain(argc, argv); } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 5a7a54c8..14ec0f0f 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -44,8 +44,6 @@ ohos_unittest("updater_unittest") { "applypatch_test/transfer_manager_unittest.cpp", "diffpatch/bzip2_unittest.cpp", "diffpatch/diffpatch_unittest.cpp", - "flashd_test/flash_host_unittest.cpp", - "flashd_test/flash_service_unittest.cpp", "fs_manager/do_partition_unittest.cpp", "log_test/log_unittest.cpp", "misc_info_test/misc_info_unittest.cpp", @@ -93,12 +91,6 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/diffpatch/patch/blocks_patch.cpp", "//base/update/updater/services/diffpatch/patch/image_patch.cpp", "//base/update/updater/services/diffpatch/patch/update_patch.cpp", - "//base/update/updater/services/flashd/blockdevice.cpp", - "//base/update/updater/services/flashd/daemon/daemon_updater.cpp", - "//base/update/updater/services/flashd/daemon/flashd_main.cpp", - "//base/update/updater/services/flashd/flash_service.cpp", - "//base/update/updater/services/flashd/host/host_updater.cpp", - "//base/update/updater/services/flashd/partition.cpp", "//base/update/updater/services/fs_manager/cmp_partition.cpp", "//base/update/updater/services/fs_manager/do_partition.cpp", "//base/update/updater/services/fs_manager/mount.cpp", @@ -164,9 +156,6 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/package/pkg_package", "//base/update/updater/services/updater_binary", "//base/update/updater/services/include/fs_manager", - "//base/update/updater/services/flashd", - "//base/update/updater/services/flashd/daemon", - "//base/update/updater/services/flashd/host", "//base/update/updater/services/fs_manager", "//base/update/updater/services/applypatch", "//base/update/updater/services/diffpatch", @@ -196,11 +185,6 @@ ohos_unittest("updater_unittest") { "//drivers/peripheral/input/hal/include", "//drivers/peripheral/input/interfaces/include", "//third_party/bounds_checking_function/include", - "//developtools/hdc_standard/src", - "//developtools/hdc_standard/src/daemon", - "//developtools/hdc_standard/src/common", - "//developtools/hdc_standard/src/host", - "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ "//base/startup/init_lite/interfaces/innerkits/fs_manager:libfsmanager_static", @@ -214,13 +198,11 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/package:libupdaterpackage", "//base/update/updater/services/ui:libui", "//base/update/updater/utils:libutils", - "//developtools/hdc_standard:hdc_deamon_flashd", "//third_party/bounds_checking_function:libsec_static", "//third_party/bzip2:libbz2", "//third_party/cJSON:cjson_static", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", - "//third_party/libuv:uv_static", "//third_party/lz4:liblz4_static", "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", @@ -237,9 +219,6 @@ ohos_unittest("updater_unittest") { defines = [ "UPDATER_UT", "BUILD_OHOS", - "HDC_DEBUG", - "HDC_SUPPORT_FLASHD", - "HARMONY_PROJECT", ] public_configs = [ ":utest_config" ] -- Gitee From 6335b55cdd7fd46ceac08581ea92a95f12141d74 Mon Sep 17 00:00:00 2001 From: zhong_ning Date: Tue, 19 Oct 2021 15:20:03 +0800 Subject: [PATCH 34/94] add init logo to misc Signed-off-by: zhong_ning --- interfaces/kits/include/misc_info/misc_info.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/interfaces/kits/include/misc_info/misc_info.h b/interfaces/kits/include/misc_info/misc_info.h index 8b260fca..38f781fd 100755 --- a/interfaces/kits/include/misc_info/misc_info.h +++ b/interfaces/kits/include/misc_info/misc_info.h @@ -23,9 +23,9 @@ namespace updater { constexpr int MAX_COMMAND_SIZE = 20; constexpr int MAX_UPDATE_SIZE = 100; +constexpr int MAX_LOGO_SIZE = 1024 * 2038; - -// misc partition offset definition. max size of misc is 1MB, do not overflow. +// misc partition offset definition. max size of misc is 2MB, do not overflow. constexpr off_t MISC_BASE_OFFSET = 0; constexpr off_t MISC_UPDATE_MESSAGE_OFFSET = MISC_BASE_OFFSET; @@ -37,6 +37,9 @@ constexpr off_t MISC_PARTITION_RECORD_SIZE = 1024; constexpr off_t MISC_RECORD_UPDATE_PARTITIONS_OFFSET = MISC_PARTITION_RECORD_OFFSET + MISC_PARTITION_RECORD_SIZE; constexpr off_t MISC_RECORD_UPDATE_PARTITIONS_SIZE = 256; +constexpr off_t MISC_RECORD_MISC_PARTITIONS_OFFSET = 1536; +constexpr off_t MISC_RECORD_MISC_PARTITIONS_SIZE = 1024 * 2038; + struct UpdateMessage { char command[MAX_COMMAND_SIZE]; char update[MAX_UPDATE_SIZE]; -- Gitee From efc5f9bf74dcbb6071066f50872d3aa05ba02679 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Tue, 19 Oct 2021 17:59:34 +0800 Subject: [PATCH 35/94] updater: fix background colour Signed-off-by: sun_fan --- services/ui/progress_bar.cpp | 28 ++++++++++++++++++++++++---- services/ui/progress_bar.h | 1 + 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/services/ui/progress_bar.cpp b/services/ui/progress_bar.cpp index 37109d84..4b8f044d 100644 --- a/services/ui/progress_bar.cpp +++ b/services/ui/progress_bar.cpp @@ -20,7 +20,6 @@ #include "securec.h" namespace updater { -constexpr int DEFAULT_PROGRESS_COLOR_A = 0xCC; constexpr int DEFAULT_NORMAL_COLOR = 0xFF; constexpr int MAX_PROGRESS_VALUE = 100; constexpr uint32_t DEFAULT_PROGRESS_COLOR = 0x00; @@ -39,8 +38,9 @@ ProgressBar::ProgressBar(const int mStartX, const int mStartY, const int w, cons progressColor_.a = DEFAULT_NORMAL_COLOR; normalColor_.r = DEFAULT_PROGRESS_COLOR; normalColor_.g = DEFAULT_PROGRESS_COLOR; - normalColor_.b = DEFAULT_PROGRESS_COLOR; - normalColor_.a = DEFAULT_PROGRESS_COLOR_A; + normalColor_.b = DEFAULT_NORMAL_COLOR; + normalColor_.a = DEFAULT_NORMAL_COLOR; + DrawBackground(); } void ProgressBar::SetProgressValue(int value) @@ -82,6 +82,7 @@ void ProgressBar::DrawProgress() void ProgressBar::OnDraw() { SyncBuffer(); + DrawBackground(); DrawProgress(); if (parent_ != nullptr) { parent_->OnDraw(); @@ -90,4 +91,23 @@ void ProgressBar::OnDraw() } return; } -} // namespace updater \ No newline at end of file + +void ProgressBar::DrawBackground() +{ + int ret = 0; + char *tmpBuf = static_cast(GetBuffer()); + BRGA888Pixel pixBuf[viewWidth_]; + for (int a = 0; a < viewWidth_; a++) { + pixBuf[a].r = normalColor_.r; + pixBuf[a].g = normalColor_.g; + pixBuf[a].b = normalColor_.b; + pixBuf[a].a = normalColor_.a; + } + for (int i = 0; i < viewHeight_; i++) { + ret = memcpy_s(tmpBuf + i * viewWidth_ * sizeof(BRGA888Pixel), viewWidth_ * sizeof(BRGA888Pixel) + 1, + reinterpret_cast(pixBuf), viewWidth_ * sizeof(BRGA888Pixel)); + UPDATER_ERROR_CHECK(ret == 0, "memcpy_s error", break); + } + return; +} +} // namespace updater diff --git a/services/ui/progress_bar.h b/services/ui/progress_bar.h index 10013971..e1f18e28 100644 --- a/services/ui/progress_bar.h +++ b/services/ui/progress_bar.h @@ -27,6 +27,7 @@ public: void SetProgressValue(int value); private: void DrawProgress(); + DrawBackground(); BRGA888Pixel progressColor_ {}; BRGA888Pixel normalColor_ {}; int pValue_ { 0 }; -- Gitee From cada48212afdf2f57f6a137d0faf3e2725e04ddf Mon Sep 17 00:00:00 2001 From: sun_fan Date: Tue, 19 Oct 2021 18:12:26 +0800 Subject: [PATCH 36/94] updater: fix bugs Signed-off-by: sun_fan --- services/ui/progress_bar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ui/progress_bar.h b/services/ui/progress_bar.h index e1f18e28..e0edd9e7 100644 --- a/services/ui/progress_bar.h +++ b/services/ui/progress_bar.h @@ -27,7 +27,7 @@ public: void SetProgressValue(int value); private: void DrawProgress(); - DrawBackground(); + void DrawBackground(); BRGA888Pixel progressColor_ {}; BRGA888Pixel normalColor_ {}; int pValue_ { 0 }; -- Gitee From cb2760b897a1a64126028e4873e0b4f3eefcb0ec Mon Sep 17 00:00:00 2001 From: sun_fan Date: Wed, 20 Oct 2021 21:18:18 +0800 Subject: [PATCH 37/94] updater: fix logo bugs Signed-off-by: sun_fan --- services/ui/progress_bar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/ui/progress_bar.cpp b/services/ui/progress_bar.cpp index 4b8f044d..4a724170 100644 --- a/services/ui/progress_bar.cpp +++ b/services/ui/progress_bar.cpp @@ -36,9 +36,9 @@ ProgressBar::ProgressBar(const int mStartX, const int mStartY, const int w, cons progressColor_.g = DEFAULT_NORMAL_COLOR; progressColor_.b = DEFAULT_NORMAL_COLOR; progressColor_.a = DEFAULT_NORMAL_COLOR; - normalColor_.r = DEFAULT_PROGRESS_COLOR; + normalColor_.r = DEFAULT_NORMAL_COLOR; normalColor_.g = DEFAULT_PROGRESS_COLOR; - normalColor_.b = DEFAULT_NORMAL_COLOR; + normalColor_.b = DEFAULT_PROGRESS_COLOR; normalColor_.a = DEFAULT_NORMAL_COLOR; DrawBackground(); } -- Gitee From 6198b9d9740c9bb6b5fdb4509b7ee203d7397fa1 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Thu, 21 Oct 2021 09:50:29 +0800 Subject: [PATCH 38/94] updater: fix codedex Signed-off-by: sun_fan --- services/ui/progress_bar.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/ui/progress_bar.cpp b/services/ui/progress_bar.cpp index 4a724170..48e474cf 100644 --- a/services/ui/progress_bar.cpp +++ b/services/ui/progress_bar.cpp @@ -24,12 +24,12 @@ constexpr int DEFAULT_NORMAL_COLOR = 0xFF; constexpr int MAX_PROGRESS_VALUE = 100; constexpr uint32_t DEFAULT_PROGRESS_COLOR = 0x00; -ProgressBar::ProgressBar(const int mStartX, const int mStartY, const int w, const int h, Frame *mParent) +ProgressBar::ProgressBar(const int StartX, const int StartY, const int w, const int h, Frame *Parent) { - startX_ = mStartX; - startY_ = mStartY; + startX_ = StartX; + startY_ = StartY; this->CreateBuffer(w, h, View::PixelFormat::BGRA888); - parent_ = mParent; + parent_ = Parent; SetFocusAble(false); parent_->ViewRegister(this); progressColor_.r = DEFAULT_NORMAL_COLOR; -- Gitee From aac82a37c2e2de673e28dd1eacc9c869dc9a8f0f Mon Sep 17 00:00:00 2001 From: sun_fan Date: Thu, 21 Oct 2021 10:11:35 +0800 Subject: [PATCH 39/94] updater: fix codedex Signed-off-by: sun_fan --- services/ui/progress_bar.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/ui/progress_bar.cpp b/services/ui/progress_bar.cpp index 48e474cf..d3df1185 100644 --- a/services/ui/progress_bar.cpp +++ b/services/ui/progress_bar.cpp @@ -24,12 +24,12 @@ constexpr int DEFAULT_NORMAL_COLOR = 0xFF; constexpr int MAX_PROGRESS_VALUE = 100; constexpr uint32_t DEFAULT_PROGRESS_COLOR = 0x00; -ProgressBar::ProgressBar(const int StartX, const int StartY, const int w, const int h, Frame *Parent) +ProgressBar::ProgressBar(const int startX, const int startY, const int w, const int h, Frame *parent) { - startX_ = StartX; - startY_ = StartY; + startX_ = startX; + startY_ = startY; this->CreateBuffer(w, h, View::PixelFormat::BGRA888); - parent_ = Parent; + parent_ = parent; SetFocusAble(false); parent_->ViewRegister(this); progressColor_.r = DEFAULT_NORMAL_COLOR; -- Gitee From 3056b6cfb806d600ab994d8e74fe067125f4bb4a Mon Sep 17 00:00:00 2001 From: sun_fan Date: Thu, 21 Oct 2021 10:19:33 +0800 Subject: [PATCH 40/94] updater: fix loger level Signed-off-by: sun_fan --- services/main.cpp | 2 +- services/updater.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/main.cpp b/services/main.cpp index e492a280..bb29543f 100644 --- a/services/main.cpp +++ b/services/main.cpp @@ -39,7 +39,7 @@ int main(int argc, char **argv) const int flashBootLength = 10; bool useFlash = memcmp(boot.command, "boot_flash", flashBootLength) == 0; InitUpdaterLogger(useFlash ? "FLASHD" : "UPDATER", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); - SetLogLevel(VERBOSE); + SetLogLevel(INFO); LoadFstab(); STAGE(UPDATE_STAGE_OUT) << "Init Params: " << boot.update; LOG(INFO) << "boot.command " << boot.command; diff --git a/services/updater.cpp b/services/updater.cpp index caccbbfe..9448d4b1 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -247,7 +247,7 @@ static void HandleChildOutput(const std::string &buffer, int32_t bufferLen, } else if (outputHeader == "set_progress") { HandleProgressSet(output); } else { - LOG(DEBUG) << "Child process returns unexpected message: " << outputHeader; + LOG(WARNING) << "Child process returns unexpected message: " << outputHeader; } } -- Gitee From ce908641d03f048f985d705a63a1a6ffced125d3 Mon Sep 17 00:00:00 2001 From: "h.hu" Date: Tue, 2 Nov 2021 19:36:14 +0800 Subject: [PATCH 41/94] fix codestyle Signed-off-by: h.hu --- services/diffpatch/diff/blocks_diff.cpp | 4 ++-- services/updater.cpp | 2 +- .../applypatch_test/imagepatch_unittest.h | 4 +--- test/unittest/package/pkg_package_unittest.cpp | 8 ++++---- .../updater_binary/updater_binary_unittest.cpp | 16 ++++++++-------- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/services/diffpatch/diff/blocks_diff.cpp b/services/diffpatch/diff/blocks_diff.cpp index d579dbd9..2a68f28c 100644 --- a/services/diffpatch/diff/blocks_diff.cpp +++ b/services/diffpatch/diff/blocks_diff.cpp @@ -237,7 +237,7 @@ void BlocksDiff::ComputeLength(const BlockBuffer &newInfo, int64_t i = 0; int64_t s = 0; int64_t tmp = 0; - for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length)); ) { + for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length));) { if (oldInfo.buffer[lastPos_ + i] == newInfo.buffer[lastScan_ + i]) { s++; } @@ -413,7 +413,7 @@ void SuffixArray::Init(const BlockBuffer &oldInfo) DataType len = 0; for (h = 1; suffixArray_[0] != -(static_cast(oldInfo.length) + 1); h += h) { len = 0; - for (i = 0; i < (static_cast(oldInfo.length) + 1); ) { + for (i = 0; i < (static_cast(oldInfo.length) + 1);) { if (suffixArray_[i] < 0) { len -= suffixArray_[i]; i -= suffixArray_[i]; diff --git a/services/updater.cpp b/services/updater.cpp index 9448d4b1..caccbbfe 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -247,7 +247,7 @@ static void HandleChildOutput(const std::string &buffer, int32_t bufferLen, } else if (outputHeader == "set_progress") { HandleProgressSet(output); } else { - LOG(WARNING) << "Child process returns unexpected message: " << outputHeader; + LOG(DEBUG) << "Child process returns unexpected message: " << outputHeader; } } diff --git a/test/unittest/applypatch_test/imagepatch_unittest.h b/test/unittest/applypatch_test/imagepatch_unittest.h index 6da5f553..e4cdc358 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.h +++ b/test/unittest/applypatch_test/imagepatch_unittest.h @@ -77,9 +77,7 @@ public: int fd = open(target.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY, mode); EXPECT_GE(fd, 0); BlockSet targetBlk; - targetBlk.ParserAndInsert({ - "2", "0", "1" - }); + targetBlk.ParserAndInsert({"2", "0", "1"}); std::unique_ptr writer = std::make_unique(fd, targetBlk); std::vector empty; int32_t ret = updatepatch::UpdatePatch::ApplyImagePatch(param, empty, diff --git a/test/unittest/package/pkg_package_unittest.cpp b/test/unittest/package/pkg_package_unittest.cpp index 2880e5cd..bdd92603 100755 --- a/test/unittest/package/pkg_package_unittest.cpp +++ b/test/unittest/package/pkg_package_unittest.cpp @@ -38,6 +38,8 @@ namespace { constexpr uint32_t MAX_FILE_NAME = 256; constexpr uint32_t CENTRAL_SIGNATURE = 0x02014b50; constexpr uint32_t END_CENTRAL_SIGNATURE = 0x06054b50; +constexpr uint32_t ZIP_NODE_ID = 100; +constexpr size_t GIANT_NUMBER = 100000; class TestFile : public PkgFile { public: @@ -120,14 +122,13 @@ public: EXPECT_NE(pkgManager_, nullptr); PkgManager::StreamPtr stream = nullptr; std::string packagePath = TEST_PATH_TO; - uint32_t zipNodeId = 100; packagePath += testPackageName; pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); EXPECT_NE(stream, nullptr); std::unique_ptr file = std::make_unique(pkgManager_, PkgStreamImpl::ConvertPkgStream(stream)); EXPECT_NE(file, nullptr); - std::unique_ptr entry = std::make_unique(file.get(), zipNodeId); + std::unique_ptr entry = std::make_unique(file.get(), ZIP_NODE_ID); EXPECT_NE(entry, nullptr); string name = "TestBigZip"; @@ -161,8 +162,7 @@ public: EXPECT_EQ(ret, 0); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length(), 1); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetHalfWord, offset4Words); - size_t giantNumber = 100000; - size_t size = UINT_MAX + giantNumber; + size_t size = UINT_MAX + GIANT_NUMBER; WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetWord, size); WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offset3Words, size); size_t decodeLen = 0; diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index 770adb21..5e97840e 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -112,26 +112,26 @@ protected: { int32_t ret; int32_t updateFileVersion = 1000; - PKG_LOGI("\n\n ************* CreatePackageBin %s \r\n", testPackageName.c_str()); + int fileNameIndex = 3; + uint8_t componentType = 22; UpgradePkgInfoExt pkgInfo; + + ComponentInfoExt *comp = (ComponentInfoExt*)malloc( + sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); + if (comp == nullptr) { + return -1; + } // C API, Cannot use c++ string class. pkgInfo.softwareVersion = strdup("100.100.100.100"); pkgInfo.date = strdup("2021-02-02"); pkgInfo.time = strdup("21:23:49"); pkgInfo.productUpdateId = strdup("555.555.100.555"); - int fileNameIndex = 3; - uint8_t componentType = 22; pkgInfo.entryCount = testFileNames_.size() + fileNameIndex; pkgInfo.updateFileVersion = updateFileVersion; pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE; - ComponentInfoExt *comp = (ComponentInfoExt*)malloc( - sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); - if (comp == nullptr) { - return -1; - } for (size_t i = 0; i < testFileNames_.size(); i++) { BuildCompnentInfo(comp[i], testFileNames_[i], testFileNames_[i], componentType); } -- Gitee From d8b27c76217764ca05db928ce73279947f60e054 Mon Sep 17 00:00:00 2001 From: "h.hu" Date: Tue, 2 Nov 2021 20:18:36 +0800 Subject: [PATCH 42/94] fix codestyle Signed-off-by: h.hu --- test/unittest/updater_binary/updater_binary_unittest.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index 5e97840e..65975e54 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -112,11 +112,10 @@ protected: { int32_t ret; int32_t updateFileVersion = 1000; - int fileNameIndex = 3; - uint8_t componentType = 22; + int fileNameIndex = 3; + uint8_t componentType = 22; UpgradePkgInfoExt pkgInfo; - - ComponentInfoExt *comp = (ComponentInfoExt*)malloc( + ComponentInfoExt *comp = (ComponentInfoExt*)malloc( sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); if (comp == nullptr) { return -1; -- Gitee From 9a73cd094a43a8d04ecdd0a791b0ee016d7cd6df Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Fri, 5 Nov 2021 15:52:48 +0800 Subject: [PATCH 43/94] updater: add flashed Signed-off-by: xionglei6 --- ohos.build | 1 + services/BUILD.gn | 1 + services/diffpatch/diff/blocks_diff.cpp | 4 +- services/flashd/BUILD.gn | 2 - services/flashd/daemon/daemon_updater.cpp | 49 ++--- services/flashd/daemon/daemon_updater.h | 9 +- services/flashd/daemon/flashd_main.cpp | 6 +- services/flashd/flash_service.cpp | 69 ++++-- services/flashd/host/host_updater.cpp | 183 ++++++++++++---- services/flashd/host/host_updater.h | 30 ++- services/flashd/partition.cpp | 43 ++-- services/include/flashd/flashd.h | 12 +- services/include/updater/updater.h | 4 +- services/include/updater/updater_const.h | 2 + services/main.cpp | 31 ++- .../package/pkg_algorithm/pkg_algo_digest.cpp | 10 +- .../package/pkg_algorithm/pkg_algo_digest.h | 2 +- .../package/pkg_algorithm/pkg_algo_sign.cpp | 16 +- .../package/pkg_algorithm/pkg_algo_sign.h | 2 +- .../package/pkg_manager/pkg_managerImpl.cpp | 3 + services/package/pkg_package/pkg_lz4file.cpp | 1 - services/ui/updater_ui.cpp | 5 +- services/updater.cpp | 4 +- services/updater_main.cpp | 7 +- services/updater_utils.cpp | 33 ++- test/unittest/BUILD.gn | 21 ++ .../applypatch_test/imagepatch_unittest.h | 4 +- .../flashd_test/flash_host_unittest.cpp | 111 ++++++++-- .../flashd_test/flash_service_unittest.cpp | 198 +++++++++++++----- test/unittest/package/package_unittest.cpp | 103 +++++---- test/unittest/package/pkg_algo_unittest.cpp | 19 +- .../unittest/package/pkg_manager_unittest.cpp | 24 +-- .../unittest/package/pkg_package_unittest.cpp | 8 +- test/unittest/package/pkg_test.h | 6 +- .../test_data/src/rsa_private_key384.pem | 39 ++++ .../test_data/src/signing_cert384.crt | 26 +++ test/unittest/test_data/updater/test.img | 16 ++ test/unittest/test_data/updater/updater.zip | 4 +- test/unittest/unittest_comm.h | 19 +- .../updater_binary_unittest.cpp | 15 +- .../updater_main_unittest.cpp | 6 +- 41 files changed, 804 insertions(+), 344 deletions(-) create mode 100755 test/unittest/test_data/src/rsa_private_key384.pem create mode 100755 test/unittest/test_data/src/signing_cert384.crt create mode 100755 test/unittest/test_data/updater/test.img diff --git a/ohos.build b/ohos.build index 9ef224ed..010ef856 100644 --- a/ohos.build +++ b/ohos.build @@ -12,6 +12,7 @@ "//base/update/updater/services:updater", "//base/update/updater/services/applypatch:libapplypatch", "//base/update/updater/services/fs_manager:libfsmanager", + "//base/update/updater/services/flashd:updater_flashd", "//base/update/updater/utils:libutils", "//base/update/updater/utils:updater_reboot", "//base/update/updater/utils:write_updater", diff --git a/services/BUILD.gn b/services/BUILD.gn index a52c4d29..945f511d 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -95,6 +95,7 @@ ohos_executable("updater") { "//base/update/updater/interfaces/kits/packages:libpackageExt", "//base/update/updater/services/applypatch:libapplypatch", "//base/update/updater/services/diffpatch/patch:libpatch", + "//base/update/updater/services/flashd:libflashd", "//base/update/updater/services/fs_manager:libfsmanager", "//base/update/updater/services/log:libupdaterlog", "//base/update/updater/services/package:libupdaterpackage", diff --git a/services/diffpatch/diff/blocks_diff.cpp b/services/diffpatch/diff/blocks_diff.cpp index 2a68f28c..d579dbd9 100644 --- a/services/diffpatch/diff/blocks_diff.cpp +++ b/services/diffpatch/diff/blocks_diff.cpp @@ -237,7 +237,7 @@ void BlocksDiff::ComputeLength(const BlockBuffer &newInfo, int64_t i = 0; int64_t s = 0; int64_t tmp = 0; - for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length));) { + for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length)); ) { if (oldInfo.buffer[lastPos_ + i] == newInfo.buffer[lastScan_ + i]) { s++; } @@ -413,7 +413,7 @@ void SuffixArray::Init(const BlockBuffer &oldInfo) DataType len = 0; for (h = 1; suffixArray_[0] != -(static_cast(oldInfo.length) + 1); h += h) { len = 0; - for (i = 0; i < (static_cast(oldInfo.length) + 1);) { + for (i = 0; i < (static_cast(oldInfo.length) + 1); ) { if (suffixArray_[i] < 0) { len -= suffixArray_[i]; i -= suffixArray_[i]; diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn index d484a64c..91407725 100755 --- a/services/flashd/BUILD.gn +++ b/services/flashd/BUILD.gn @@ -26,7 +26,6 @@ ohos_static_library("libflashd") { ] defines = [ - "HDC_DEBUG", "HDC_SUPPORT_FLASHD", "HARMONY_PROJECT", ] @@ -46,7 +45,6 @@ ohos_static_library("libflashd") { "//third_party/libuv:uv_static", "//third_party/lz4:liblz4_static", "//third_party/openssl:libcrypto_static", - "//third_party/openssl:ssl_source", "//third_party/zlib:libz", "//utils/native/base:utils", ] diff --git a/services/flashd/daemon/daemon_updater.cpp b/services/flashd/daemon/daemon_updater.cpp index 37dae05c..1cd520b7 100755 --- a/services/flashd/daemon/daemon_updater.cpp +++ b/services/flashd/daemon/daemon_updater.cpp @@ -29,14 +29,6 @@ DaemonUpdater::~DaemonUpdater() WRITE_LOG(LOG_DEBUG, "~DaemonUpdater refCount %d", refCount); } -bool DaemonUpdater::ReadyForRelease() -{ - if (!HdcTaskBase::ReadyForRelease()) { - return false; - } - return true; -} - bool DaemonUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) { #ifndef UPDATER_UT @@ -49,15 +41,17 @@ bool DaemonUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, co [&](uint32_t type, size_t dataLen, const void *context) { SendProgress(dataLen); }); - if (ret != 0) { - return false; - } + FLASHDAEMON_CHECK(ret == 0, AsyncUpdateFinish(command, -1, errorMsg_); + return false, "Faild to create flashd"); } switch (command) { case CMD_UPDATER_DATA: { string serialStrring((char *)payload, payloadPrefixReserve); - TransferPayload pld; + TransferPayload pld {}; SerialStruct::ParseFromString(pld, serialStrring); +#ifdef UPDATER_UT + pld.uncompressSize = pld.compressSize; +#endif SendProgress(pld.uncompressSize); break; } @@ -88,9 +82,7 @@ void DaemonUpdater::ProcessUpdateCheck(const uint8_t *payload, const int payload { uint64_t realSize = 0; int ret = memcpy_s(&realSize, sizeof(realSize), payload, sizeof(realSize)); - if (ret != 0) { - return; - } + FLASHDAEMON_CHECK(ret == 0, return, "Faild to memcpy"); string bufString((char *)payload + sizeof(realSize), payloadSize - sizeof(realSize)); SerialStruct::ParseFromString(ctxNow.transferConfig, bufString); ctxNow.master = false; @@ -117,6 +109,7 @@ void DaemonUpdater::ProcessUpdateCheck(const uint8_t *payload, const int payload } else { WRITE_LOG(LOG_FATAL, "ProcessUpdateCheck local function %s size %lu realSize %lu", ctxNow.transferConfig.functionName.c_str(), ctxNow.fileSize, realSize); + AsyncUpdateFinish(type, -1, "Invalid command"); return; } ctxNow.localPath = ctxNow.transferConfig.optionalName; @@ -124,34 +117,31 @@ void DaemonUpdater::ProcessUpdateCheck(const uint8_t *payload, const int payload if (ret == 0) { refCount++; WRITE_LOG(LOG_DEBUG, "ProcessUpdateCheck localPath %s", ctxNow.localPath.c_str()); +#ifndef UPDATER_UT uv_fs_open(loopTask, &ctxNow.fsOpenReq, ctxNow.localPath.c_str(), UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IRUSR, OnFileOpen); - } else { - AsyncUpdateFinish(type, ret, errorMsg_); +#endif } + FLASHDAEMON_CHECK(ret == 0, AsyncUpdateFinish(type, ret, errorMsg_), "Faild to prepare for %d", type); } void DaemonUpdater::RunUpdateShell(uint8_t type, const std::string &options, const std::string &package) { int ret = flashd::DoUpdaterFlash(flashHandle_, type, options, package); - if (ret != 0) { - WRITE_LOG(LOG_FATAL, errorMsg_.c_str()); - } AsyncUpdateFinish(type, ret, errorMsg_); } void DaemonUpdater::SendProgress(size_t dataLen) { currSize_ += dataLen; - int32_t percentage = (int32_t)(currSize_ * (flashd::PERCENT_FINISH - 1) / totalSize_); - if (percentage >= flashd::PERCENT_FINISH) { + int32_t percentage = static_cast(currSize_ * (flashd::PERCENT_FINISH - 1) / totalSize_); + if (static_cast(percentage) >= flashd::PERCENT_FINISH) { WRITE_LOG(LOG_DEBUG, "SendProgress %lf percentage %d", currSize_, percentage); return; } if (percentage_ < percentage) { percentage_ = percentage; WRITE_LOG(LOG_DEBUG, "SendProgress %lf percentage_ %d", currSize_, percentage_); - FLASHING_LOGI("SendProgress %lf percentage_ %d", currSize_, percentage_); SendToAnother(CMD_UPDATER_PROGRESS, (uint8_t *)&percentage, sizeof(uint32_t)); } } @@ -172,24 +162,21 @@ void DaemonUpdater::WhenTransferFinish(CtxFile *context) type = flashd::UPDATEMOD_FLASH; } AsyncUpdateFinish(type, ret, errorMsg_); - ret = flashd::DoUpdaterFinish(flashHandle_, type, ctxNow.localPath); - if (ret != 0) { - WRITE_LOG(LOG_FATAL, errorMsg_.c_str()); - } TaskFinish(); } -void DaemonUpdater::AsyncUpdateFinish(uint8_t type, int32_t ret, const string &result) +void DaemonUpdater::AsyncUpdateFinish(uint8_t type, int32_t retCode, const string &result) { - WRITE_LOG(LOG_DEBUG, "AsyncUpdateFinish ret %d result %s", ret, result.c_str()); - uint32_t percentage = (ret != 0) ? flashd::PERCENT_CLEAR : flashd::PERCENT_FINISH; + WRITE_LOG(LOG_DEBUG, "AsyncUpdateFinish retCode %d result %s", retCode, result.c_str()); + uint32_t percentage = (retCode != 0) ? flashd::PERCENT_CLEAR : flashd::PERCENT_FINISH; SendToAnother(CMD_UPDATER_PROGRESS, (uint8_t *)&percentage, sizeof(uint32_t)); + (void)flashd::DoUpdaterFinish(flashHandle_, type, ctxNow.localPath); string echo = result; echo = Base::ReplaceAll(echo, "\n", " "); vector vecBuf; vecBuf.push_back(type); - if (ret != 0) { + if (retCode != 0) { vecBuf.push_back(MSG_FAIL); } else { vecBuf.push_back(MSG_OK); diff --git a/services/flashd/daemon/daemon_updater.h b/services/flashd/daemon/daemon_updater.h index a7e35b67..6f7bb76f 100755 --- a/services/flashd/daemon/daemon_updater.h +++ b/services/flashd/daemon/daemon_updater.h @@ -20,12 +20,17 @@ #include "transfer.h" namespace Hdc { +#define FLASHDAEMON_CHECK(retCode, exper, ...) \ + if (!(retCode)) { \ + WRITE_LOG(LOG_FATAL, __VA_ARGS__); \ + exper; \ + } + class DaemonUpdater : public HdcTransferBase { public: explicit DaemonUpdater(HTaskInfo hTaskInfo); virtual ~DaemonUpdater(); bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) override; - bool ReadyForRelease(); #ifdef UPDATER_UT void DoTransferFinish(); #endif @@ -33,7 +38,7 @@ private: virtual void WhenTransferFinish(CtxFile *context) override; void ProcessUpdateCheck(const uint8_t *payload, const int payloadSize); void RunUpdateShell(uint8_t type, const std::string &options, const std::string &package); - void AsyncUpdateFinish(uint8_t type, int32_t ret, const string &result); + void AsyncUpdateFinish(uint8_t type, int32_t retCode, const string &result); void SendProgress(size_t dataLen); #ifdef UPDATER_UT bool SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size) diff --git a/services/flashd/daemon/flashd_main.cpp b/services/flashd/daemon/flashd_main.cpp index 5d73fd8f..18d8ebd6 100755 --- a/services/flashd/daemon/flashd_main.cpp +++ b/services/flashd/daemon/flashd_main.cpp @@ -27,10 +27,8 @@ int flashd_main(int argc, char **argv) for (std::string arg : args) { if (arg.find("-l") != std::string::npos) { int logLevel = atoi(arg.c_str() + strlen("-l")); - if (logLevel < 0 || logLevel > LOG_LAST) { - WRITE_LOG(LOG_DEBUG, "Loglevel error!\n"); - return -1; - } + FLASHDAEMON_CHECK(!(logLevel < 0 || logLevel > LOG_LAST), + logLevel = LOG_LAST, "Loglevel error %d", logLevel); Base::SetLogLevel(logLevel); } else if (arg.find("-t") != std::string::npos) { enableTcp = true; diff --git a/services/flashd/flash_service.cpp b/services/flashd/flash_service.cpp index 1cd136b5..4b49ef7e 100755 --- a/services/flashd/flash_service.cpp +++ b/services/flashd/flash_service.cpp @@ -38,6 +38,7 @@ using namespace hpackage; using namespace updater; namespace flashd { +static std::atomic g_flashdRunning { false }; FlashService::~FlashService() { for (auto part : partitions_) { @@ -84,7 +85,12 @@ int FlashService::DoUpdate(const std::string &packageName) FLASHING_CHECK(ret == PKG_SUCCESS, PkgManager::ReleasePackageInstance(pkgManager); RecordMsg(updater::ERROR, "Can not load package %s", packageName.c_str()); return FLASHING_PACKAGE_INVALID, "Failed to load package %s", packageName.c_str()); -#ifndef LOCAL_SUPPORT + + ret = UpdatePreProcess(pkgManager, packageName); + FLASHING_CHECK(ret == PKG_SUCCESS, PkgManager::ReleasePackageInstance(pkgManager); + RecordMsg(updater::ERROR, "Invalid package %s", packageName.c_str()); + return FLASHING_PACKAGE_INVALID, "Invalid package %s", packageName.c_str()); +#ifndef UPDATER_UT ret = updater::ExecUpdate(pkgManager, 0, [&](const char *cmd, const char *content) { if (strncmp(cmd, "data", strlen(cmd)) == 0) { @@ -93,6 +99,9 @@ int FlashService::DoUpdate(const std::string &packageName) } }); #endif + FLASHING_CHECK(ret == PKG_SUCCESS, PkgManager::ReleasePackageInstance(pkgManager); + RecordMsg(updater::ERROR, "Failed to update package %s", packageName.c_str()); + return FLASHING_PACKAGE_INVALID, "Failed to update package %s", packageName.c_str()); FLASHING_LOGI("Load packageName %s success %llu", packageName.c_str(), pkgLen); PkgManager::ReleasePackageInstance(pkgManager); return ret; @@ -227,7 +236,7 @@ int FlashService::LoadBlockDevice(const std::string &fileDir) continue; } std::string devPath = fileDir + "/" + entry->d_name; - if (entry->d_type == 10) { // 10 link 文件 + if (entry->d_type == 10) { // 10 link file readlink(devPath.c_str(), buffer.data(), DEVICE_PATH_SIZE); devPath = fileDir + "/" + buffer.data(); memset_s(buffer.data(), DEVICE_PATH_SIZE, 0, DEVICE_PATH_SIZE); @@ -241,13 +250,13 @@ int FlashService::LoadBlockDevice(const std::string &fileDir) } ret = 0; if (SCSI_BLK_MAJOR(devMajor)) { - if ((devMinor % 0x10) == 0) { + if ((devMinor % 0x10) == 0) { // 0x10 scsi device ret = AddNewBlockDevice(DeviceType::DEVICE_SCSI, devPath); } else { partitionsName.push_back(devPath); } } else if (devMajor == SDMMC_MAJOR) { - if (devMinor % 0x08 == 0) { + if (devMinor % 0x08 == 0) { // 0x08 emmc ret = AddNewBlockDevice(DeviceType::DEVICE_EMMC, devPath); } else { partitionsName.push_back(devPath); @@ -343,19 +352,20 @@ int FlashService::ExecCommand(const std::vector &cmds) } extractedCmds.push_back(nullptr); pid_t pid = fork(); - if (pid < 0) { - FLASHING_CHECK(0, return -1, "Failed to fork %d error:%d", pid, errno); - return errno; - } if (pid == 0) { +#ifndef UPDATER_UT execv(extractedCmds[0], extractedCmds.data()); +#endif exit(0x7f); // 0x7f exit code } + FLASHING_CHECK(pid > 0, return -1, "Failed to fork %d error:%d", pid, errno); +#ifndef UPDATER_UT int status; waitpid(pid, &status, 0); if (WEXITSTATUS(status) != 0 || !WIFEXITED(status)) { return WEXITSTATUS(status); } +#endif return 0; } @@ -381,9 +391,7 @@ void FlashService::PostProgress(uint32_t type, size_t dataLen, const void *conte int FlashService::CheckOperationPermission(int type, const std::string &partition) const { - if (type >= UPDATEMOD_MAX) { - return 1; - } + FLASHING_CHECK(type < UPDATEMOD_MAX, return 1, "Invalid type %d", type); std::vector forbitPartName[] = { {}, // updater {"updater"}, // flash @@ -511,13 +519,19 @@ static int GetCmdParam(uint8_t type, const std::string &origString, int CreateFlashInstance(FlashHandle *handle, std::string &errorMsg, ProgressFunction progressor) { + int mode = BOOT_UPDATER; + int ret = updater::GetBootMode(mode); + FLASHING_CHECK(ret == 0 && mode == BOOT_FLASHD, errorMsg = "Boot mode is not in flashd"; + return FLASHING_SYSTEM_ERROR, "Boot mode error"); + + FLASHING_CHECK(!g_flashdRunning, errorMsg = "Flashd has been running"; + return FLASHING_SYSTEM_ERROR, "Flashd has been running"); + g_flashdRunning = true; + FLASHING_CHECK(handle != nullptr, return FLASHING_ARG_INVALID, "Invalid handle"); flashd::FlashService *flash = new flashd::FlashService(errorMsg, progressor); - if (flash == nullptr) { - FLASHING_LOGE("Failed to create flash service"); - errorMsg = "Create instance fail"; - return FLASHING_SYSTEM_ERROR; - } + FLASHING_CHECK(flash != nullptr, errorMsg = "Failed to create flash service"; + return FLASHING_SYSTEM_ERROR, "Failed to create flash service"); *handle = static_cast(flash); return 0; } @@ -538,12 +552,12 @@ int DoUpdaterPrepare(FlashHandle handle, uint8_t type, const std::string &cmdPar // 检查剩余分区大小,扩展分区 const std::string root = flashd::FlashService::GetPathRoot(FLASHD_FILE_PATH); ret = MountForPath(root); - FLASHING_CHECK(ret == 0, + FLASHING_CHECK(ret == 0, g_flashdRunning = false; flash->RecordMsg(updater::ERROR, "Failed to mount data paratition for %s", filePath.c_str()); return FLASHING_INVALID_SPACE, "Failed to mount data paratition for %s", filePath.c_str()); ret = flash->DoResizeParatiton(root, MIN_BLOCKS_FOR_UPDATE); - FLASHING_CHECK(ret == 0, return ret, "Failed to resize partition"); + FLASHING_CHECK(ret == 0, g_flashdRunning = false; return ret, "Failed to resize partition"); if (access(FLASHD_FILE_PATH.c_str(), F_OK) == -1) { mkdir(FLASHD_FILE_PATH.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); } @@ -567,23 +581,24 @@ int DoUpdaterFlash(FlashHandle handle, uint8_t type, const std::string &cmdParam std::vector params {}; int ret = GetCmdParam(type, cmdParam, {"-f"}, params); - FLASHING_CHECK(ret == 0, + FLASHING_CHECK(ret == 0, g_flashdRunning = false; flash->RecordMsg(updater::ERROR, "Invalid param for %d", type); return FLASHING_ARG_INVALID, "Invalid param for %d", type); FLASHING_DEBUG("DoUpdaterFlash type: %d param %s filePath %s", type, cmdParam.c_str(), filePath.c_str()); switch (type) { case flashd::UPDATEMOD_UPDATE: { ret = flash->DoUpdate(filePath); - unlink(filePath.c_str()); break; } case flashd::UPDATEMOD_ERASE: - FLASHING_CHECK(params.size() > 1, return FLASHING_ARG_INVALID, "Invalid param size for erase"); + FLASHING_CHECK(params.size() > 1, g_flashdRunning = false; + return FLASHING_ARG_INVALID, "Invalid param size for erase"); ret = flash->DoErasePartition(params[1]); break; case flashd::UPDATEMOD_FORMAT: { std::string fsType = GetValueFromParam(params, "-t", "ext4"); - FLASHING_CHECK(params.size() > 1, return FLASHING_ARG_INVALID, "Invalid param size for format"); + FLASHING_CHECK(params.size() > 1, g_flashdRunning = false; + return FLASHING_ARG_INVALID, "Invalid param size for format"); ret = flash->DoFormatPartition(params[1], fsType); break; } @@ -598,15 +613,23 @@ int DoUpdaterFinish(FlashHandle handle, uint8_t type, const std::string &partiti { FLASHING_CHECK(handle != nullptr, return FLASHING_ARG_INVALID, "Invalid handle for %d", type); FLASHING_DEBUG("DoUpdaterFinish type: %d %s", type, partition.c_str()); - updater::PostUpdater(); switch (type) { case flashd::UPDATEMOD_UPDATE: { +#ifndef UPDATER_UT + unlink(partition.c_str()); +#endif + updater::PostUpdater(true); utils::DoReboot(""); break; } + case flashd::UPDATEMOD_FLASH: { + updater::PostUpdater(false); + break; + } default: break; } + g_flashdRunning = false; return 0; } } // namespace flashd diff --git a/services/flashd/host/host_updater.cpp b/services/flashd/host/host_updater.cpp index 4de625d3..641af6ac 100755 --- a/services/flashd/host/host_updater.cpp +++ b/services/flashd/host/host_updater.cpp @@ -13,11 +13,18 @@ * limitations under the License. */ #include "host_updater.h" + +#include #include "common.h" #include "transfer.h" #include "serial_struct.h" namespace Hdc { +static const std::string helpCmd = "flash"; +static const std::string updateCmd = "update "; +static const std::string flashCmd = "flash "; +static const std::string eraseCmd = "erase "; +static const std::string formatCmd = "format "; static const int PERCENT_FINISH = 100; static const uint32_t PERCENT_CLEAR = ((uint32_t)-1); HostUpdater::HostUpdater(HTaskInfo hTaskInfo) : HdcTransferBase(hTaskInfo) @@ -41,24 +48,20 @@ bool HostUpdater::BeginTransfer(CtxFile &context, { int argc = 0; char **argv = Base::SplitCommandToArgs(payload, &argc); - if (argv == nullptr || argc < minParam || fileIndex >= argc) { - LogMsg(MSG_FAIL, "Invalid param for cmd \"%s\"", function.c_str()); - delete[]((char *)argv); - return false; - } + FLASHHOST_CHECK(!(argv == nullptr || argc < minParam || fileIndex >= argc), delete[]((char *)argv); + return false, "Invalid param for cmd \"%s\"", function.c_str()); + int maxParam = minParam; - if (strstr(payload, "-f") != nullptr) { + bool force = strstr(payload, "-f") != nullptr; + if (force) { maxParam += 1; } - if (argc != maxParam) { - LogMsg(MSG_FAIL, "Invalid param for cmd \"%s\"", function.c_str()); - delete[]((char *)argv); - return false; - } + FLASHHOST_CHECK(argc == maxParam, delete[]((char *)argv); + return false, "Invalid param for cmd \"%s\" %d", function.c_str(), maxParam); context.transferConfig.functionName = function; context.transferConfig.options = payload; - if (strcmp(argv[fileIndex], "-f") == 0) { + if (force && (fileIndex + 1 < argc) && strcmp(argv[fileIndex + 1], "-f") != 0) { context.localPath = argv[fileIndex + 1]; } else { context.localPath = argv[fileIndex]; @@ -66,27 +69,26 @@ bool HostUpdater::BeginTransfer(CtxFile &context, if (MatchPackageExtendName(context.localPath, ".img")) { context.transferConfig.compressType = COMPRESS_NONE; - } else if (function == CMDSTR_FLASH_PARTITION) { - context.transferConfig.compressType = COMPRESS_NONE; } else if (MatchPackageExtendName(context.localPath, ".bin")) { + const char *part = strstr(payload, "fastboot"); + FLASHHOST_CHECK(part != nullptr, delete[]((char *)argv); + return false, "Invalid image %s for cmd \"%s\"", context.localPath.c_str(), function.c_str()); context.transferConfig.compressType = COMPRESS_NONE; - } else if (!(MatchPackageExtendName(context.localPath, ".zip") || - MatchPackageExtendName(context.localPath, ".lz4") || - MatchPackageExtendName(context.localPath, ".gz2"))) { - LogMsg(MSG_FAIL, "Invaid file \"%s\" for cmd \"%s\"", context.localPath.c_str(), function.c_str()); - delete[]((char *)argv); - return false; + } else { + FLASHHOST_CHECK((MatchPackageExtendName(context.localPath, ".zip") || + MatchPackageExtendName(context.localPath, ".lz4") || + MatchPackageExtendName(context.localPath, ".gz2")), delete[]((char *)argv); + return false, + "Invaid extend name \"%s\" for cmd \"%s\"", context.localPath.c_str(), function.c_str()); } WRITE_LOG(LOG_DEBUG, "BeginTransfer function: %s localPath: %s command: %s ", context.transferConfig.functionName.c_str(), context.localPath.c_str(), payload); // check path bool ret = Base::CheckDirectoryOrPath(context.localPath.c_str(), true, true); - if (!ret) { - LogMsg(MSG_FAIL, "Invaid file \"%s\" for cmd \"%s\"", context.localPath.c_str(), function.c_str()); - delete[]((char *)argv); - return false; - } + FLASHHOST_CHECK(ret, delete[]((char *)argv); + return false, + "Invaid path \"%s\" for cmd \"%s\"", context.localPath.c_str(), function.c_str()); context.taskQueue.push_back(context.localPath); RunQueue(context); return true; @@ -95,7 +97,7 @@ bool HostUpdater::BeginTransfer(CtxFile &context, std::string HostUpdater::GetFileName(const std::string &fileName) const { int32_t pos = fileName.find_last_of('/'); - if (pos < 0) { + if (pos < 0) { // win32 pos = fileName.find_last_of('\\'); } return fileName.substr(pos + 1, fileName.size()); @@ -132,15 +134,10 @@ bool HostUpdater::CheckCmd(const std::string &function, const char *payload, int { int argc = 0; char **argv = Base::SplitCommandToArgs(payload, &argc); - if (argv == nullptr) { - LogMsg(MSG_FAIL, "Can not parser cmd \"%s\"", function.c_str()); - return false; - } + FLASHHOST_CHECK(argv != nullptr, return false, "Can not parser cmd \"%s\"", function.c_str()); delete[]((char *)argv); - if (argc < param) { - LogMsg(MSG_FAIL, "Invalid param for cmd \"%s\"", function.c_str()); - return false; - } + FLASHHOST_CHECK(argc >= param, return false, "Invalid param for cmd \"%s\" %d", function.c_str(), argc); + WRITE_LOG(LOG_DEBUG, "CheckCmd command: %s ", payload); int maxParam = param; if (strstr(payload, "-f") != nullptr) { @@ -150,10 +147,8 @@ bool HostUpdater::CheckCmd(const std::string &function, const char *payload, int maxParam += 1; maxParam += 1; } - if (argc != maxParam) { - LogMsg(MSG_FAIL, "Invalid param for cmd \"%s\"", function.c_str()); - return false; - } + FLASHHOST_CHECK(argc == maxParam, return false, + "Invalid param for cmd \"%s\" %d %d", function.c_str(), argc, maxParam); return true; } @@ -161,9 +156,11 @@ bool HostUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, cons { const int cmdFroErase = 2; const int cmdFroFormat = 2; +#ifndef UPDATER_UT if (!HdcTransferBase::CommandDispatch(command, payload, payloadSize)) { return false; } +#endif bool ret = true; switch (command) { case CMD_UPDATER_BEGIN: { @@ -226,9 +223,7 @@ void HostUpdater::ProcessProgress(uint32_t percentage) return; } int len = sprintf_s(buffer.data(), buffer.size() - 1, "%s Processing: %3d%%", backStr.c_str(), percentage); - if (len <= 0) { - return; - } + FLASHHOST_CHECK(len > 0, return, "Failed to format progress info "); SendRawData(reinterpret_cast(buffer.data()), len); if (percentage == PERCENT_FINISH) { SendRawData(reinterpret_cast(breakStr.data()), breakStr.size()); @@ -238,9 +233,8 @@ void HostUpdater::ProcessProgress(uint32_t percentage) bool HostUpdater::CheckUpdateContinue(const uint16_t command, const uint8_t *payload, int payloadSize) { - if (static_cast(payloadSize) < sizeof(uint16_t)) { - return false; - } + FLASHHOST_CHECK(static_cast(payloadSize) >= sizeof(uint16_t), + return false, "Failed to check payload size %d ", payloadSize); MessageLevel level = (MessageLevel)payload[1]; if ((level == MSG_OK) && bSendProgress) { ProcessProgress(PERCENT_FINISH); @@ -249,12 +243,109 @@ bool HostUpdater::CheckUpdateContinue(const uint16_t command, const uint8_t *pay if (!info.empty()) { LogMsg(level, "%s", info.c_str()); } - WRITE_LOG(LOG_DEBUG, "CheckUpdateContinue %d %s", level, info.c_str()); - ctxNow.taskQueue.pop_back(); + WRITE_LOG(LOG_DEBUG, "CheckUpdateContinue payloadSize %d %d %s", payloadSize, level, info.c_str()); + if (ctxNow.taskQueue.size() != 0) { + ctxNow.taskQueue.pop_back(); + } if (singalStop || !ctxNow.taskQueue.size()) { return false; } RunQueue(ctxNow); return true; } + +std::string HostUpdater::GetFlashdHelp() +{ + string help; + help = "\n---------------------------------flash commands:-------------------------------------\n" + "flash commands:\n" + " target boot [-flashd] - Reboot the device or boot into flashd\n" + " update packagename - Update system by package\n" + " flash [-f] partition imagename - Flash partition by image\n" + " erase [-f] partition - Erase partition\n" + " format [-f] partition -t fs_type - Format partition -t [ext4 | f2fs]\n"; + return help; +} + +bool HostUpdater::CheckMatchUpdate(const std::string &input, + std::string &stringError, uint16_t &cmdFlag, bool &bJumpDo) +{ + WRITE_LOG(LOG_DEBUG, "CheckMatchUpdate command:%s", input.c_str()); + if (!strcmp(input.c_str(), helpCmd.c_str())) { + cmdFlag = CMD_KERNEL_HELP; + stringError = HostUpdater::GetFlashdHelp(); + bJumpDo = true; + return true; + } + int cmdLen = updateCmd.size(); + if (!strncmp(input.c_str(), updateCmd.c_str(), updateCmd.size())) { + cmdFlag = CMD_UPDATER_UPDATE_INIT; + cmdLen = updateCmd.size(); + } else if (!strncmp(input.c_str(), flashCmd.c_str(), flashCmd.size())) { + cmdFlag = CMD_UPDATER_FLASH_INIT; + cmdLen = flashCmd.size(); + } else if (!strncmp(input.c_str(), eraseCmd.c_str(), eraseCmd.size())) { + cmdFlag = CMD_UPDATER_ERASE; + cmdLen = eraseCmd.size(); + } else if (!strncmp(input.c_str(), formatCmd.c_str(), formatCmd.size())) { + cmdFlag = CMD_UPDATER_FORMAT; + cmdLen = formatCmd.size(); + } else { + return false; + } + if (input.size() <= cmdLen) { + stringError = "Incorrect command"; + bJumpDo = true; + } + return true; +} + +bool HostUpdater::ConfirmCommand(const string &commandIn) +{ + bool needConfirm = false; + std::string tip = ""; + WRITE_LOG(LOG_DEBUG, "ConfirmCommand \"%s\" \n", commandIn.c_str()); + + if (!strncmp(commandIn.c_str(), flashCmd.c_str(), flashCmd.size())) { + tip = "Confirm flash partition"; + } else if (!strncmp(commandIn.c_str(), eraseCmd.c_str(), eraseCmd.size())) { + tip = "Confirm erase partition"; + } else if (!strncmp(commandIn.c_str(), formatCmd.c_str(), formatCmd.size())) { + tip = "Confirm format partition"; + } + if (tip.empty()) { + return true; + } + // check if -f + if (strstr(commandIn.c_str(), " -f") != nullptr) { + return true; + } + const size_t minLen = strlen("yes"); + do { + printf(" %s ? (Yes/No) ", tip.c_str()); + fflush(stdin); + std::string info = {}; + size_t i = 0; + while (1) { + char c = getchar(); + if (c == '\r' || c == '\n') { + break; + } + if (c == ' ') { + continue; + } + if (i < minLen && isprint(c)) { + info.append(1, std::tolower(c)); + i++; + } + } + if (info == "n" || info == "no") { + return false; + } + if (info == "y" || info == "yes") { + return true; + } + } while (1); + return true; +} } // namespace Hdc \ No newline at end of file diff --git a/services/flashd/host/host_updater.h b/services/flashd/host/host_updater.h index 08e5ec78..9329419a 100755 --- a/services/flashd/host/host_updater.h +++ b/services/flashd/host/host_updater.h @@ -18,12 +18,31 @@ #include "transfer.h" namespace Hdc { +#define FLASHHOST_CHECK(retCode, exper, ...) \ + if (!(retCode)) { \ + LogMsg(MSG_FAIL, __VA_ARGS__); \ + exper; \ + } +#define FLASHHOST_ONLY_CHECK(retCode, exper) \ + if (!(retCode)) { \ + exper; \ + } + class HostUpdater : public HdcTransferBase { public: explicit HostUpdater(HTaskInfo hTaskInfo); virtual ~HostUpdater(); bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) override; + static std::string GetFlashdHelp(); + static bool CheckMatchUpdate(const std::string &input, std::string &stringError, uint16_t &cmdFlag, bool &bJumpDo); + static bool ConfirmCommand(const string &commandIn); +#ifdef UPDATER_UT + void OpenFile() + { + CheckMaster(&ctxNow); + } +#endif private: void CheckMaster(CtxFile *context) override; @@ -36,20 +55,17 @@ private: #ifdef UPDATER_UT void LogMsg(MessageLevel level, const char *msg, ...) { - va_list vaArgs; - va_start(vaArgs, msg); - string log = Base::StringFormat(msg, vaArgs); - va_end(vaArgs); - WRITE_LOG(LOG_DEBUG, "LogMsg %d %s", level, log.c_str()); return; } void SendRawData(uint8_t *bufPtr, const int size) { - WRITE_LOG(LOG_DEBUG, "SendRawData %d", size); + std::string s((char *)bufPtr, size); + WRITE_LOG(LOG_DEBUG, "SendRawData %d %s", size, s.c_str()); } bool SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size) { - WRITE_LOG(LOG_DEBUG, "SendToAnother command %d size %d", command, size); + std::string s((char *)bufPtr, size); + WRITE_LOG(LOG_DEBUG, "SendToAnother command %d size %d %s", command, size, s.c_str()); return true; } #endif diff --git a/services/flashd/partition.cpp b/services/flashd/partition.cpp index 75d0f1d8..aa4264f0 100755 --- a/services/flashd/partition.cpp +++ b/services/flashd/partition.cpp @@ -106,12 +106,16 @@ int Partition::DoErase() if (ret < 0) { range[0] = 0; range[1] = size; +#ifndef UPDATER_UT ret = ioctl(fd_, BLKDISCARD, &range); +#endif FLASHING_CHECK(ret >= 0, flash_->RecordMsg(updater::ERROR, "Failed to erase \"%s\" error: %s", partName_.c_str(), strerror(errno)); return ret, "Failed to erase %s error: %s", partName_.c_str(), strerror(errno)); std::vector buffer(BLOCK_SIZE, 0); +#ifndef UPDATER_UT ret = updater::utils::WriteFully(fd_, buffer.data(), buffer.size()); +#endif FLASHING_CHECK(ret == 0, return FLASHING_PART_WRITE_ERROR, "Failed to flash data errno %d", errno); fsync(fd_); } @@ -121,11 +125,9 @@ int Partition::DoErase() int Partition::DoFormat(const std::string &fsType) { - if (mountPoint_ == "/") { /* Can not format root */ - return 0; - } int ret = DoUmount(); FLASHING_CHECK(ret == 0, return FLASHING_PART_WRITE_ERROR, "Failed to umount partition"); + FLASHING_LOGI("DoFormat partition %s format %s", partName_.c_str(), fsType_.c_str()); std::vector formatCmds {}; ret = BuildCommandParam(fsType, formatCmds); @@ -150,15 +152,6 @@ int Partition::DoResize(uint32_t blocks) bool needResize = false; if (!mountPoint_.empty()) { needResize = FlashService::CheckFreeSpace(mountPoint_, blocks); - } else { - ret = Open(); - FLASHING_CHECK(ret == 0, return ret, "Can not open partiton %s for erase", partName_.c_str()); - uint64_t size = GetBlockDeviceSize(fd_); - FLASHING_LOGI("DoResise partition %s size %lu", partName_.c_str(), size); - close(fd_); - fd_ = -1; - uint64_t min = static_cast(DEFAULT_BLOCK_SIZE) * static_cast(blocks); - needResize = size < min; } if (!needResize) { FLASHING_LOGI("No need to resize partition %s", partName_.c_str()); @@ -184,10 +177,9 @@ int Partition::DoResize(uint32_t blocks) int Partition::Open() { - if (fd_ != -1) { - return 0; + if (fd_ <= 0) { + fd_ = open(partPath_.c_str(), O_RDWR); } - fd_ = open(partPath_.c_str(), O_RDWR); FLASHING_CHECK(fd_ > 0, flash_->RecordMsg(updater::ERROR, "Can not open partiton \"%s\" error: %s", partName_.c_str(), strerror(errno)); @@ -211,12 +203,9 @@ int Partition::WriteRowData(int inputFd, size_t fileSize, std::vector & totalWrite += writeLen; // continue read and write - ssize_t ret = read(inputFd, buffer.data(), buffer.size()); - if (ret <= 0) { - break; - } - - flash_->PostProgress(UPDATEMOD_FLASH, dataSize, nullptr); + ssize_t ret = read(inputFd, buffer.data(), dataSize); + FLASHING_CHECK(ret > 0, return -1, "Failed to read data %d %d", errno, buffer.size()); + flash_->PostProgress(UPDATEMOD_FLASH, writeLen, nullptr); dataLen = ret; } while (1); fsync(fd_); @@ -227,9 +216,7 @@ int Partition::IsBlockDevice(int fd) const { struct stat st {}; int ret = fstat(fd, &st); - if (ret < 0) { - return 0; - } + FLASHING_CHECK(ret >= 0, return 0, "Invalid get fstate %d", errno); return S_ISBLK(st.st_mode); } @@ -299,11 +286,13 @@ int Partition::DoUmount() if (mountPoint_.empty()) { return 0; } +#ifndef UPDATER_UT int ret = umount2(mountPoint_.c_str(), MNT_FORCE); FLASHING_CHECK(ret == 0, flash_->RecordMsg(updater::ERROR, "Failed to umount \"%s\" error: %s", partName_.c_str(), strerror(errno)); return FLASHING_PART_WRITE_ERROR, "Failed to umount \"%s\" error: %s", partName_.c_str(), strerror(errno)); - return ret; +#endif + return 0; } int Partition::DoMount() @@ -324,7 +313,11 @@ int Partition::DoMount() std::string data; uint32_t flags = GetMountFlags(mountFlags_, data); errno = 0; + while ((ret = mount(partPath_.c_str(), mountPoint_.c_str(), fsType_.c_str(), flags, data.c_str()) != 0)) { +#ifdef UPDATER_UT + ret = 0; +#endif if (errno == EAGAIN) { continue; } else { diff --git a/services/include/flashd/flashd.h b/services/include/flashd/flashd.h index 8eae9598..8d46b976 100755 --- a/services/include/flashd/flashd.h +++ b/services/include/flashd/flashd.h @@ -44,21 +44,19 @@ static constexpr uint16_t MAX_SIZE_BUF = 1024; static constexpr uint32_t PERCENT_FINISH = 100; static constexpr uint32_t PERCENT_CLEAR = (uint32_t)-1; -#ifndef LOCAL_SUPPORT const std::string FORMAT_TOOL_FOR_EXT4 = "/bin/mke2fs"; const std::string FORMAT_TOOL_FOR_F2FS = "/bin/make_f2fs"; const std::string RESIZE_TOOL = "/bin/resize2fs"; + +#ifndef UPDATER_UT const std::string FLASHD_FILE_PATH = "/data/updater/"; const std::string FLASHD_HDC_LOG_PATH = "/tmp/flashd_hdc.log"; #else -const std::string FORMAT_TOOL_FOR_EXT4 = "/usr/sbin/mke2fs"; -const std::string FORMAT_TOOL_FOR_F2FS = "/system/bin/make_f2fs"; -const std::string RESIZE_TOOL = "/bin/resize2fs"; -const std::string FLASHD_FILE_PATH = "/home/axw/develop/build/"; -const std::string FLASHD_HDC_LOG_PATH = "/home/axw/develop/build/hdc.log"; +const std::string FLASHD_FILE_PATH = "/data/updater/updater/"; +const std::string FLASHD_HDC_LOG_PATH = "/data/updater/flashd_hdc.log"; #endif static constexpr uint32_t MIN_BLOCKS_FOR_UPDATE = 1024 * 1024; -static constexpr uint32_t DEFAULT_BLOCK_SIZE = 4096; +static constexpr uint32_t DEFAULT_BLOCK_SIZE = 2048; static constexpr uint32_t DEFAULT_SIZE_UNIT = 1024 * 1024; using FlashHandle = void *; diff --git a/services/include/updater/updater.h b/services/include/updater/updater.h index 0d94c5ab..272c301a 100644 --- a/services/include/updater/updater.h +++ b/services/include/updater/updater.h @@ -52,8 +52,10 @@ int IsSpaceCapacitySufficient(const std::string &packagePath); bool IsSDCardExist(const std::string &sdcard_path); -void PostUpdater(); +void PostUpdater(bool clearMisc); std::vector ParseParams(int argc, char **argv); + +int GetBootMode(int &mode); } // updater #endif /* UPDATER_UPDATER_H */ diff --git a/services/include/updater/updater_const.h b/services/include/updater/updater_const.h index 88775927..6b447687 100644 --- a/services/include/updater/updater_const.h +++ b/services/include/updater/updater_const.h @@ -75,5 +75,7 @@ constexpr unsigned int UI_SHOW_DURATION = 2000; constexpr unsigned int INTERVAL_TIME = 300; constexpr float EPSINON = 0.00001; constexpr float FULL_EPSINON = 1; +constexpr int BOOT_FLASHD = 1; +constexpr int BOOT_UPDATER = 2; } // namespace updater #endif diff --git a/services/main.cpp b/services/main.cpp index bb29543f..6f5d5fe9 100644 --- a/services/main.cpp +++ b/services/main.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "fs_manager/mount.h" +#include "flashd/flashd.h" #include "log/log.h" #include "misc_info/misc_info.h" #include "updater/updater_const.h" @@ -22,27 +23,19 @@ using namespace updater; int main(int argc, char **argv) { - struct UpdateMessage boot {}; - // read from misc - bool ret = ReadUpdaterMessage(MISC_FILE, boot); - if (!ret) { - printf("ReadUpdaterMessage MISC_FILE failed!\n"); + int mode = BOOT_UPDATER; + int ret = GetBootMode(mode); + if (ret != 0) { + printf("Failed to get boot mode, start updater mode \n"); + mode = BOOT_UPDATER; } - // if boot.update is empty, read from command.The Misc partition may have dirty data, - // so strlen(boot.update) is not used, which can cause system exceptions. - if (boot.update[0] == '\0' && !access(COMMAND_FILE.c_str(), 0)) { - ret = ReadUpdaterMessage(COMMAND_FILE, boot); - if (!ret) { - printf("ReadUpdaterMessage COMMAND_FILE failed!\n"); - } - } - const int flashBootLength = 10; - bool useFlash = memcmp(boot.command, "boot_flash", flashBootLength) == 0; - InitUpdaterLogger(useFlash ? "FLASHD" : "UPDATER", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); + + InitUpdaterLogger((mode == BOOT_FLASHD) ? "FLASHD" : "UPDATER", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); SetLogLevel(INFO); LoadFstab(); - STAGE(UPDATE_STAGE_OUT) << "Init Params: " << boot.update; - LOG(INFO) << "boot.command " << boot.command; - LOG(INFO) << "boot.update " << boot.update; + STAGE(UPDATE_STAGE_OUT) << "Start " << ((mode == BOOT_FLASHD) ? "flashd" : "updater"); + if (mode == BOOT_FLASHD) { + return flashd::flashd_main(argc, argv); + } return updater::UpdaterMain(argc, argv); } diff --git a/services/package/pkg_algorithm/pkg_algo_digest.cpp b/services/package/pkg_algorithm/pkg_algo_digest.cpp index 1855aa67..0c1b8934 100644 --- a/services/package/pkg_algorithm/pkg_algo_digest.cpp +++ b/services/package/pkg_algorithm/pkg_algo_digest.cpp @@ -39,7 +39,11 @@ size_t DigestAlgorithm::GetSignatureLen(int8_t digestMethod) uint8_t DigestAlgorithm::GetDigestMethod(std::string version) { - return PKG_DIGEST_TYPE_SHA256; + if (version == "3") { + return PKG_DIGEST_TYPE_SHA384; + } else { + return PKG_DIGEST_TYPE_SHA256; + } } int32_t Crc32Algorithm::Init() @@ -120,7 +124,7 @@ int32_t Sha384Algorithm::Update(const PkgBuffer &buffer, size_t size) int32_t Sha384Algorithm::Final(PkgBuffer &result) { - PKG_CHECK(result.buffer != nullptr && result.length == DIGEST_SHA384_LEN, + PKG_CHECK(result.buffer != nullptr && result.length == 64, // 64 length return PKG_INVALID_PARAM, "Param context null!"); SHA384_Final(result.buffer, &shaCtx_); return PKG_SUCCESS; @@ -128,7 +132,7 @@ int32_t Sha384Algorithm::Final(PkgBuffer &result) int32_t Sha384Algorithm::Calculate(PkgBuffer &result, const PkgBuffer &buffer, size_t size) { - PKG_CHECK(result.buffer != nullptr && result.length == DIGEST_SHA384_LEN, + PKG_CHECK(result.buffer != nullptr && result.length == 64, // 64 length return PKG_INVALID_PARAM, "Param context null!"); PKG_CHECK(buffer.buffer != nullptr, return PKG_INVALID_PARAM, "Param null!"); SHA512_Init(&shaCtx_); diff --git a/services/package/pkg_algorithm/pkg_algo_digest.h b/services/package/pkg_algorithm/pkg_algo_digest.h index 4b08139d..a83c1328 100644 --- a/services/package/pkg_algorithm/pkg_algo_digest.h +++ b/services/package/pkg_algorithm/pkg_algo_digest.h @@ -21,7 +21,7 @@ namespace hpackage { constexpr uint32_t DIGEST_CRC_LEN = 4; constexpr uint32_t DIGEST_SHA256_LEN = 32; -constexpr uint32_t DIGEST_SHA384_LEN = 64; +constexpr uint32_t DIGEST_SHA384_LEN = 48; constexpr uint32_t SIGN_SHA256_LEN = 256; constexpr uint32_t SIGN_SHA384_LEN = 384; constexpr uint32_t SIGN_TOTAL_LEN = 384 + 256; diff --git a/services/package/pkg_algorithm/pkg_algo_sign.cpp b/services/package/pkg_algorithm/pkg_algo_sign.cpp index fd258ded..b0f9d9cc 100644 --- a/services/package/pkg_algorithm/pkg_algo_sign.cpp +++ b/services/package/pkg_algorithm/pkg_algo_sign.cpp @@ -85,14 +85,20 @@ int32_t SignAlgorithmEcc::SignBuffer(const PkgBuffer &buffer, std::vector &digest, const int hashNid = NID_sha1; if (certs.hashLen == SHA256_DIGEST_LENGTH) { hashNid = NID_sha256; + } else if (certs.hashLen == SHA384_DIGEST_LENGTH) { + hashNid = NID_sha384; } int ret = 0; if (certs.keyType == KEY_TYPE_RSA) { diff --git a/services/package/pkg_algorithm/pkg_algo_sign.h b/services/package/pkg_algorithm/pkg_algo_sign.h index eb0900fd..f8c6a68c 100644 --- a/services/package/pkg_algorithm/pkg_algo_sign.h +++ b/services/package/pkg_algorithm/pkg_algo_sign.h @@ -75,7 +75,7 @@ public: private: bool CheckEccKey(const EC_KEY *eccKey) const; - bool CheckRsaKey(const RSA *rsakey) const; + bool CheckRsaKey(const RSA *rsakey, int &hashLen) const; bool LoadPubKey(const std::string &filename, struct CertKeySt &certs) const; }; diff --git a/services/package/pkg_manager/pkg_managerImpl.cpp b/services/package/pkg_manager/pkg_managerImpl.cpp index 684536c0..aa895157 100644 --- a/services/package/pkg_manager/pkg_managerImpl.cpp +++ b/services/package/pkg_manager/pkg_managerImpl.cpp @@ -104,6 +104,7 @@ int32_t PkgManagerImpl::CreatePackage(const std::string &path, const std::string if (pkgFile == nullptr) { return PKG_INVALID_FILE; } + offset = (header->digestMethod == PKG_DIGEST_TYPE_SHA384) ? (offset + SIGN_SHA256_LEN) : offset; ret = Sign(pkgFile->GetPkgStream(), offset, header); delete pkgFile; return ret; @@ -120,6 +121,7 @@ int32_t PkgManagerImpl::CreatePackage(const std::string &path, const std::string if (pkgFile == nullptr) { return PKG_INVALID_FILE; } + offset = (header->digestMethod == PKG_DIGEST_TYPE_SHA384) ? (offset + SIGN_SHA256_LEN) : offset; ret = Sign(pkgFile->GetPkgStream(), offset, header); delete pkgFile; return ret; @@ -136,6 +138,7 @@ int32_t PkgManagerImpl::CreatePackage(const std::string &path, const std::string if (pkgFile == nullptr) { return PKG_INVALID_FILE; } + offset = (header->digestMethod == PKG_DIGEST_TYPE_SHA384) ? (offset + SIGN_SHA256_LEN) : offset; ret = Sign(pkgFile->GetPkgStream(), offset, header); delete pkgFile; return ret; diff --git a/services/package/pkg_package/pkg_lz4file.cpp b/services/package/pkg_package/pkg_lz4file.cpp index 372c9cdc..96d8f4ca 100644 --- a/services/package/pkg_package/pkg_lz4file.cpp +++ b/services/package/pkg_package/pkg_lz4file.cpp @@ -130,7 +130,6 @@ int32_t Lz4PkgFile::AddEntry(const PkgManager::FileInfoPtr file, const PkgStream PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Pack for %s", file->identity.c_str()); currentOffset_ += encodeLen; PKG_LOGI("offset:%zu ", currentOffset_); - pkgStream_->Flush(currentOffset_); return PKG_SUCCESS; } diff --git a/services/ui/updater_ui.cpp b/services/ui/updater_ui.cpp index bf15c482..edcbc93c 100644 --- a/services/ui/updater_ui.cpp +++ b/services/ui/updater_ui.cpp @@ -162,7 +162,7 @@ void OnKeyEvent(int viewId) ClearText(); if (viewId == g_textLabel0->GetViewId() && g_textLabel0->IsVisiable()) { HideDialog(); - PostUpdater(); + PostUpdater(true); utils::DoReboot(""); } else if (viewId == g_textLabel2->GetViewId() && g_textLabel2->IsVisiable()) { ShowDialog(); @@ -174,7 +174,7 @@ void OnKeyEvent(int viewId) ShowMenu(); return; } - PostUpdater(); + PostUpdater(true); utils::DoReboot(""); } else if (viewId == g_dialogCancalBtn->GetViewId() && g_dialogCancalBtn->IsVisiable()) { HideDialog(); @@ -439,6 +439,7 @@ void UpdaterUiInit() g_anmimationLabel->SetBackgroundColor(&bgColor); LoadImgs(); g_progressBar = new ProgressBar(START_X3, START_Y3, WIDTH3, HEIGHT3, g_updateFrame); + g_progressBar->Hide(); g_updateInfoLabel = new TextLabel(START_X5, START_Y5, screenW, HEIGHT5, g_updateFrame); g_updateInfoLabel->SetOutLineBold(false, false); diff --git a/services/updater.cpp b/services/updater.cpp index caccbbfe..3aa34d74 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -153,9 +153,7 @@ UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, cons // Only handle UPATE_ERROR and UPDATE_SUCCESS here. // If it returns UPDATE_CORRUPT, which means something wrong with package manager. // Let package verify handle this. - if (ret == UPDATE_SPACE_NOTENOUGH) { - ShowText(GetUpdateInfoLabel(), "Free space is not enough"); - } else if (ret == UPDATE_ERROR) { + if (ret == UPDATE_SPACE_NOTENOUGH || ret == UPDATE_ERROR) { return ret; } else if (ret == UPDATE_SUCCESS) { pkgManager = PkgManager::GetPackageInstance(); diff --git a/services/updater_main.cpp b/services/updater_main.cpp index c4b40a2c..9b393a6d 100644 --- a/services/updater_main.cpp +++ b/services/updater_main.cpp @@ -170,7 +170,8 @@ static UpdaterStatus InstallUpdaterPackage(UpdaterParams &upParams, const std::v status = DoInstallUpdaterPackage(manager, upParams.updatePackage, upParams.retryCount); if (status != UPDATE_SUCCESS) { std::this_thread::sleep_for(std::chrono::milliseconds(UI_SHOW_DURATION)); - g_logLabel->SetText("update failed!"); + std::string errMsg = ((status == UPDATE_SPACE_NOTENOUGH) ? "Free space is not enough" : "Update failed!"); + g_logLabel->SetText(errMsg.c_str()); STAGE(UPDATE_STAGE_FAIL) << "Install failed"; if (status == UPDATE_RETRY && upParams.retryCount < MAX_RETRY_COUNT) { upParams.retryCount += 1; @@ -222,7 +223,7 @@ static UpdaterStatus StartUpdaterEntry(PkgManager::PkgManagerPtr manager, g_logResultLabel->SetText("Wipe data failed"); } else { g_logResultLabel->SetText("Wipe data finished"); - PostUpdater(); + PostUpdater(true); std::this_thread::sleep_for(std::chrono::milliseconds(UI_SHOW_DURATION)); } } @@ -297,7 +298,7 @@ int UpdaterMain(int argc, char **argv) return 0; } #endif - PostUpdater(); + PostUpdater(true); utils::DoReboot(""); return 0; } diff --git a/services/updater_utils.cpp b/services/updater_utils.cpp index 0abd3ca1..bd4e7927 100755 --- a/services/updater_utils.cpp +++ b/services/updater_utils.cpp @@ -196,7 +196,7 @@ void PostUpdaterForSdcard(std::string &updaterLogPath, std::string &stageLogPath return; } -void PostUpdater() +void PostUpdater(bool clearMisc) { STAGE(UPDATE_STAGE_BEGIN) << "PostUpdater"; std::string updaterLogPath = "/data/updater/log/updater_log"; @@ -204,7 +204,9 @@ void PostUpdater() std::string errorCodePath = "/data/updater/log/error_code.log"; PostUpdaterForSdcard(updaterLogPath, stageLogPath, errorCodePath); // clear update misc partition. - UPDATER_ERROR_CHECK_NOT_RETURN(ClearMisc() == true, "PostUpdater clear misc failed"); + if (clearMisc) { + UPDATER_ERROR_CHECK_NOT_RETURN(ClearMisc() == true, "PostUpdater clear misc failed"); + } if (!access(COMMAND_FILE.c_str(), 0)) { UPDATER_ERROR_CHECK_NOT_RETURN(unlink(COMMAND_FILE.c_str()) == 0, "Delete command failed"); } @@ -287,4 +289,31 @@ std::vector ParseParams(int argc, char **argv) parseParams.insert(parseParams.end(), parseParams1.begin(), parseParams1.end()); return parseParams; } + +int GetBootMode(int &mode) +{ +#ifndef UPDATER_UT + mode = BOOT_UPDATER; +#else + mode = BOOT_FLASHD; +#endif + struct UpdateMessage boot {}; + // read from misc + bool ret = ReadUpdaterMessage(MISC_FILE, boot); + if (!ret) { + return -1; + } + // if boot.update is empty, read from command.The Misc partition may have dirty data, + // so strlen(boot.update) is not used, which can cause system exceptions. + if (boot.update[0] == '\0' && !access(COMMAND_FILE.c_str(), 0)) { + ret = ReadUpdaterMessage(COMMAND_FILE, boot); + if (!ret) { + return -1; + } + } + if (memcmp(boot.command, "boot_flash", strlen("boot_flash")) == 0) { + mode = BOOT_FLASHD; + } + return 0; +} } // namespace updater diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 14ec0f0f..5a7a54c8 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -44,6 +44,8 @@ ohos_unittest("updater_unittest") { "applypatch_test/transfer_manager_unittest.cpp", "diffpatch/bzip2_unittest.cpp", "diffpatch/diffpatch_unittest.cpp", + "flashd_test/flash_host_unittest.cpp", + "flashd_test/flash_service_unittest.cpp", "fs_manager/do_partition_unittest.cpp", "log_test/log_unittest.cpp", "misc_info_test/misc_info_unittest.cpp", @@ -91,6 +93,12 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/diffpatch/patch/blocks_patch.cpp", "//base/update/updater/services/diffpatch/patch/image_patch.cpp", "//base/update/updater/services/diffpatch/patch/update_patch.cpp", + "//base/update/updater/services/flashd/blockdevice.cpp", + "//base/update/updater/services/flashd/daemon/daemon_updater.cpp", + "//base/update/updater/services/flashd/daemon/flashd_main.cpp", + "//base/update/updater/services/flashd/flash_service.cpp", + "//base/update/updater/services/flashd/host/host_updater.cpp", + "//base/update/updater/services/flashd/partition.cpp", "//base/update/updater/services/fs_manager/cmp_partition.cpp", "//base/update/updater/services/fs_manager/do_partition.cpp", "//base/update/updater/services/fs_manager/mount.cpp", @@ -156,6 +164,9 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/package/pkg_package", "//base/update/updater/services/updater_binary", "//base/update/updater/services/include/fs_manager", + "//base/update/updater/services/flashd", + "//base/update/updater/services/flashd/daemon", + "//base/update/updater/services/flashd/host", "//base/update/updater/services/fs_manager", "//base/update/updater/services/applypatch", "//base/update/updater/services/diffpatch", @@ -185,6 +196,11 @@ ohos_unittest("updater_unittest") { "//drivers/peripheral/input/hal/include", "//drivers/peripheral/input/interfaces/include", "//third_party/bounds_checking_function/include", + "//developtools/hdc_standard/src", + "//developtools/hdc_standard/src/daemon", + "//developtools/hdc_standard/src/common", + "//developtools/hdc_standard/src/host", + "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ "//base/startup/init_lite/interfaces/innerkits/fs_manager:libfsmanager_static", @@ -198,11 +214,13 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/package:libupdaterpackage", "//base/update/updater/services/ui:libui", "//base/update/updater/utils:libutils", + "//developtools/hdc_standard:hdc_deamon_flashd", "//third_party/bounds_checking_function:libsec_static", "//third_party/bzip2:libbz2", "//third_party/cJSON:cjson_static", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", + "//third_party/libuv:uv_static", "//third_party/lz4:liblz4_static", "//third_party/openssl:libcrypto_static", "//third_party/openssl:ssl_source", @@ -219,6 +237,9 @@ ohos_unittest("updater_unittest") { defines = [ "UPDATER_UT", "BUILD_OHOS", + "HDC_DEBUG", + "HDC_SUPPORT_FLASHD", + "HARMONY_PROJECT", ] public_configs = [ ":utest_config" ] diff --git a/test/unittest/applypatch_test/imagepatch_unittest.h b/test/unittest/applypatch_test/imagepatch_unittest.h index e4cdc358..6da5f553 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.h +++ b/test/unittest/applypatch_test/imagepatch_unittest.h @@ -77,7 +77,9 @@ public: int fd = open(target.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY, mode); EXPECT_GE(fd, 0); BlockSet targetBlk; - targetBlk.ParserAndInsert({"2", "0", "1"}); + targetBlk.ParserAndInsert({ + "2", "0", "1" + }); std::unique_ptr writer = std::make_unique(fd, targetBlk); std::vector empty; int32_t ret = updatepatch::UpdatePatch::ApplyImagePatch(param, empty, diff --git a/test/unittest/flashd_test/flash_host_unittest.cpp b/test/unittest/flashd_test/flash_host_unittest.cpp index c4e6d023..fe97130e 100755 --- a/test/unittest/flashd_test/flash_host_unittest.cpp +++ b/test/unittest/flashd_test/flash_host_unittest.cpp @@ -29,8 +29,8 @@ using namespace Hdc; using namespace testing::ext; namespace { static std::string TEST_PARTITION_NAME = "data"; -static std::string TEST_UPDATER_PACKAGE_PATH = "/data/updater/src/updater.zip"; -static std::string TEST_FLASH_IMAGE_NAME = "/data/updater/src/image/userdata.img"; +static std::string TEST_UPDATER_PACKAGE_PATH = "/data/updater/updater/updater.zip"; +static std::string TEST_FLASH_IMAGE_NAME = "/data/updater/updater/test.img"; class FLashHostUnitTest : public testing::Test { public: @@ -51,54 +51,123 @@ public: HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); + if (task == nullptr) { + return -1; + } hTaskInfo = task.get(); hTaskInfo->channelId = 1; hTaskInfo->sessionId = 0; hTaskInfo->runLoop = &loopMain; hTaskInfo->serverOrDaemon = 0; std::shared_ptr flashHost = std::make_shared(hTaskInfo); + if (flashHost == nullptr) { + return -1; + } flashHost->CommandDispatch(command, const_cast(reinterpret_cast(cmd.data())), cmd.size()); return 0; } + + int TestFlashProgress(uint16_t command, const std::string &cmd, uint32_t progress) + { + uv_loop_t loopMain; + uv_loop_init(&loopMain); + + HTaskInfo hTaskInfo = nullptr; + std::shared_ptr task = std::make_shared(); + if (task == nullptr) { + return -1; + } + hTaskInfo = task.get(); + hTaskInfo->channelId = 1; + hTaskInfo->sessionId = 0; + hTaskInfo->runLoop = &loopMain; + hTaskInfo->serverOrDaemon = 0; + std::shared_ptr flashHost = std::make_shared(hTaskInfo); + if (flashHost == nullptr) { + return -1; + } + flashHost->CommandDispatch(command, + const_cast(reinterpret_cast(cmd.data())), cmd.size()); + flashHost->OpenFile(); + + std::vector data(MAX_SIZE_IOBUF * 2); // 2 + flashHost->CommandDispatch(CMD_UPDATER_BEGIN, const_cast(data.data()), data.size()); + + std::string cmdInfo = ""; + flashHost->CommandDispatch(CMD_UPDATER_CHECK, + const_cast(reinterpret_cast(cmdInfo.data())), cmdInfo.size()); + + flashHost->CommandDispatch(CMD_UPDATER_DATA, const_cast(data.data()), data.size()); + + vector info = {0, 1, 's', 'u', 'c', 'c', 'e', 's', 's'}; + flashHost->CommandDispatch(CMD_UPDATER_FINISH, + const_cast(reinterpret_cast(info.data())), info.size()); + + uint32_t percentage = 30; // 30 progress + cmdInfo.resize(sizeof(percentage)); + (void)memcpy_s(cmdInfo.data(), cmdInfo.size(), &percentage, sizeof(percentage)); + flashHost->CommandDispatch(CMD_UPDATER_PROGRESS, + const_cast(reinterpret_cast(cmdInfo.data())), cmdInfo.size()); + + percentage = (uint32_t)progress; + cmdInfo.resize(sizeof(percentage)); + (void)memcpy_s(cmdInfo.data(), cmdInfo.size(), &percentage, sizeof(percentage)); + flashHost->CommandDispatch(CMD_UPDATER_PROGRESS, + const_cast(reinterpret_cast(cmdInfo.data())), cmdInfo.size()); + + return 0; + } }; HWTEST_F(FLashHostUnitTest, TestFlashHost, TestSize.Level1) { FLashHostUnitTest test; + Base::SetLogLevel(LOG_LAST); // debug log print - std::string cmdParam = "update "; - cmdParam += TEST_UPDATER_PACKAGE_PATH; + std::string cmdParam = TEST_UPDATER_PACKAGE_PATH; EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_UPDATE_INIT, cmdParam)); - cmdParam = "flash "; + cmdParam = " -f "; cmdParam += TEST_PARTITION_NAME + " "; cmdParam += TEST_FLASH_IMAGE_NAME; EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FLASH_INIT, cmdParam)); - cmdParam = ""; - EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_CHECK, cmdParam)); - - cmdParam = ""; - EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_BEGIN, cmdParam)); - - cmdParam = ""; - EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_DATA, cmdParam)); - - cmdParam = ""; - EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FINISH, cmdParam)); - cmdParam = "erase -f "; cmdParam += TEST_PARTITION_NAME; EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_ERASE, cmdParam)); cmdParam = "format -f "; cmdParam += TEST_PARTITION_NAME; + cmdParam += " -t ext4"; EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FORMAT, cmdParam)); +} + +HWTEST_F(FLashHostUnitTest, TestFlashProgress, TestSize.Level1) +{ + FLashHostUnitTest test; + Base::SetLogLevel(LOG_LAST); // debug log print + + std::string cmdParam = TEST_UPDATER_PACKAGE_PATH; + EXPECT_EQ(0, test.TestFlashProgress(CMD_UPDATER_UPDATE_INIT, cmdParam, -1)); - uint32_t percentage = 30; // 30 progress - cmdParam.resize(sizeof(percentage)); - memcpy_s(cmdParam.data(), cmdParam.size(), &percentage, sizeof(percentage)); - EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_PROGRESS, cmdParam)); + cmdParam = " -f "; + cmdParam += TEST_PARTITION_NAME + " "; + cmdParam += TEST_FLASH_IMAGE_NAME; + EXPECT_EQ(0, test.TestFlashProgress(CMD_UPDATER_FLASH_INIT, cmdParam, -1)); +} + +HWTEST_F(FLashHostUnitTest, TestFlashProgressFinish, TestSize.Level1) +{ + FLashHostUnitTest test; + Base::SetLogLevel(LOG_LAST); // debug log print + + std::string cmdParam = TEST_UPDATER_PACKAGE_PATH; + EXPECT_EQ(0, test.TestFlashProgress(CMD_UPDATER_UPDATE_INIT, cmdParam, 100)); + + cmdParam = " -f "; + cmdParam += TEST_PARTITION_NAME + " "; + cmdParam += TEST_FLASH_IMAGE_NAME; + EXPECT_EQ(0, test.TestFlashProgress(CMD_UPDATER_FLASH_INIT, cmdParam, 100)); } } // namespace \ No newline at end of file diff --git a/test/unittest/flashd_test/flash_service_unittest.cpp b/test/unittest/flashd_test/flash_service_unittest.cpp index 64b37920..3a33c1cf 100755 --- a/test/unittest/flashd_test/flash_service_unittest.cpp +++ b/test/unittest/flashd_test/flash_service_unittest.cpp @@ -23,6 +23,7 @@ #include "daemon_updater.h" #include "flash_service.h" #include "flashd/flashd.h" +#include "fs_manager/mount.h" #include "serial_struct.h" #include "unittest_comm.h" @@ -30,10 +31,11 @@ using namespace std; using namespace flashd; using namespace Hdc; using namespace testing::ext; + namespace { static std::string TEST_PARTITION_NAME = "data"; -static std::string TEST_UPDATER_PACKAGE_PATH = "/home/axw/develop/updater.zip"; -static std::string TEST_FLASH_IMAGE_NAME = "/home/axw/develop/image/userdata.img"; +static std::string TEST_UPDATER_PACKAGE_PATH = "/data/updater/updater/updater.zip"; +static std::string TEST_FLASH_IMAGE_NAME = "/data/updater/updater/updater.zip"; class FLashServiceUnitTest : public testing::Test { public: @@ -49,6 +51,7 @@ public: public: int TestFindAllDevice() { + updater::LoadFstab(); std::string errorMsg; std::shared_ptr flash = std::make_shared(errorMsg); if (flash == nullptr) { @@ -69,6 +72,18 @@ public: return 0; } + int TestDoUpdater() + { + std::string errorMsg; + std::shared_ptr flash = std::make_shared(errorMsg); + if (flash == nullptr) { + return 1; + } + flash->DoUpdate(TEST_UPDATER_PACKAGE_PATH); + flash->PostProgress(UPDATEMOD_UPDATE, 1024 * 1024 * 4, nullptr); // 1024 * 1024 * 4 4M + return 0; + } + int TestDoErasePartition() { std::string errorMsg; @@ -80,14 +95,26 @@ public: return 0; } - int TestDoFormatPartition() + int TestDoFormatPartition(const std::string &part, const std::string &type) { std::string errorMsg; std::shared_ptr flash = std::make_shared(errorMsg); if (flash == nullptr) { return 1; } - flash->DoFormatPartition(TEST_PARTITION_NAME, "ext4"); + flash->DoFormatPartition(part, type); + return 0; + } + + int TestFlashServiceDoResizeParatiton() + { + std::string errorMsg; + std::shared_ptr flash = std::make_shared(errorMsg); + if (flash == nullptr) { + return 1; + } + flash->DoResizeParatiton("data", 4096); // 4096 partition size + flash->DoResizeParatiton("data", 1024); // 1024 partition size return 0; } @@ -131,12 +158,18 @@ public: HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); + if (task == nullptr) { + return -1; + } hTaskInfo = task.get(); hTaskInfo->channelId = 1; hTaskInfo->sessionId = 0; hTaskInfo->runLoop = &loopMain; hTaskInfo->serverOrDaemon = 1; std::shared_ptr hdcDamon = std::make_shared(hTaskInfo); + if (hdcDamon == nullptr) { + return -1; + } // cmd: hdc updater packagename // check @@ -148,7 +181,6 @@ public: WRITE_LOG(LOG_DEBUG, "CheckMaster %s", transferConfig.functionName.c_str()); transferConfig.optionalName = "updater.zip"; std::string bufString = SerialStruct::SerializeToString(transferConfig); - // 当前升级包中总的文件的大小 const uint64_t realSize = static_cast(1024 * 1024 * 1024) * 5; std::vector buffer(sizeof(realSize) + bufString.size()); int ret = memcpy_s(buffer.data(), buffer.size(), &realSize, sizeof(realSize)); @@ -160,41 +192,80 @@ public: // begin hdcDamon->CommandDispatch(CMD_UPDATER_BEGIN, NULL, 0); - // data 写数据部分 - const uint32_t dataSize = 1024; // 1024 data size - HdcTransferBase::TransferPayload payloadHead {}; - payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; - payloadHead.uncompressSize = dataSize; - payloadHead.compressSize = dataSize; - payloadHead.index = 0; - std::string bufData = SerialStruct::SerializeToString(payloadHead); - hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); - - payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; - payloadHead.uncompressSize = dataSize; - payloadHead.compressSize = dataSize; - payloadHead.index = 1; - bufData = SerialStruct::SerializeToString(payloadHead); - hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); + for (int i = 0; i < 100; i++) { // 10 send time + HdcTransferBase::TransferPayload payloadHead {}; + payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; + payloadHead.uncompressSize = transferConfig.fileSize / 10; // 10 time + payloadHead.compressSize = transferConfig.fileSize / 10; // 10 time + payloadHead.index = 0; + std::string bufData = SerialStruct::SerializeToString(payloadHead); + hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); + } // end hdcDamon->DoTransferFinish(); return 0; } - int TestHdcDaemonFlash() + int TestHdcDaemonInvalid() { uv_loop_t loopMain; uv_loop_init(&loopMain); HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); + if (task == nullptr) { + return -1; + } hTaskInfo = task.get(); hTaskInfo->channelId = 2; // 2 channel id hTaskInfo->sessionId = 0; hTaskInfo->runLoop = &loopMain; hTaskInfo->serverOrDaemon = 1; std::shared_ptr hdcDamon = std::make_shared(hTaskInfo); + if (hdcDamon == nullptr) { + return -1; + } + // cmd: hdc flash partition packagename + // check + HdcTransferBase::TransferConfig transferConfig {}; + transferConfig.functionName = "aaaa"; + transferConfig.options = TEST_PARTITION_NAME; + transferConfig.options += " "; + transferConfig.options += TEST_FLASH_IMAGE_NAME; + std::string localPath = TEST_FLASH_IMAGE_NAME; + transferConfig.fileSize = 1468006400; // 1468006400 file size + WRITE_LOG(LOG_DEBUG, "CheckMaster %s", transferConfig.functionName.c_str()); + transferConfig.optionalName = "userdata.img"; + std::string bufString = SerialStruct::SerializeToString(transferConfig); + const uint64_t realSize = static_cast(1024 * 1024 * 1024) * 5; + std::vector buffer(sizeof(realSize) + bufString.size()); + int ret = memcpy_s(buffer.data(), buffer.size(), &realSize, sizeof(realSize)); + EXPECT_EQ(0, ret); + ret = memcpy_s(buffer.data() + sizeof(realSize), buffer.size(), bufString.c_str(), bufString.size()); + EXPECT_EQ(0, ret); + hdcDamon->CommandDispatch(CMD_UPDATER_CHECK, buffer.data(), buffer.size()); + return 0; + } + int TestHdcDaemonFlash() + { + uv_loop_t loopMain; + uv_loop_init(&loopMain); + + HTaskInfo hTaskInfo = nullptr; + std::shared_ptr task = std::make_shared(); + if (task == nullptr) { + return -1; + } + hTaskInfo = task.get(); + hTaskInfo->channelId = 2; // 2 channel id + hTaskInfo->sessionId = 0; + hTaskInfo->runLoop = &loopMain; + hTaskInfo->serverOrDaemon = 1; + std::shared_ptr hdcDamon = std::make_shared(hTaskInfo); + if (hdcDamon == nullptr) { + return -1; + } // cmd: hdc flash partition packagename // check HdcTransferBase::TransferConfig transferConfig {}; @@ -207,8 +278,7 @@ public: WRITE_LOG(LOG_DEBUG, "CheckMaster %s", transferConfig.functionName.c_str()); transferConfig.optionalName = "userdata.img"; std::string bufString = SerialStruct::SerializeToString(transferConfig); - // 当前升级包中总的文件的大小 - const uint64_t realSize = static_cast(1024 * 1024 * 1024) * 5; + const uint64_t realSize = transferConfig.fileSize; std::vector buffer(sizeof(realSize) + bufString.size()); int ret = memcpy_s(buffer.data(), buffer.size(), &realSize, sizeof(realSize)); EXPECT_EQ(0, ret); @@ -219,22 +289,21 @@ public: // begin hdcDamon->CommandDispatch(CMD_UPDATER_BEGIN, NULL, 0); - // data 写数据部分 - const uint32_t dataSize = 1024; // 1024 data size HdcTransferBase::TransferPayload payloadHead {}; + for (int i = 0; i < 10; i++) { // 10 send data + payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; + payloadHead.uncompressSize = transferConfig.fileSize / 10; // 10 time + payloadHead.compressSize = transferConfig.fileSize / 10; // 10 time + payloadHead.index = 0; + std::string bufData = SerialStruct::SerializeToString(payloadHead); + hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); + } payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; - payloadHead.uncompressSize = dataSize; - payloadHead.compressSize = dataSize; + payloadHead.uncompressSize = transferConfig.fileSize / 10; // 10 time + payloadHead.compressSize = transferConfig.fileSize / 10; // 10 time payloadHead.index = 0; std::string bufData = SerialStruct::SerializeToString(payloadHead); hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); - - payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; - payloadHead.uncompressSize = dataSize; - payloadHead.compressSize = dataSize; - payloadHead.index = 1; - bufData = SerialStruct::SerializeToString(payloadHead); - hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); // end hdcDamon->DoTransferFinish(); return 0; @@ -247,20 +316,22 @@ public: HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); + if (task == nullptr) { + return -1; + } hTaskInfo = task.get(); hTaskInfo->channelId = 2; // 2 channel id hTaskInfo->sessionId = 0; hTaskInfo->runLoop = &loopMain; hTaskInfo->serverOrDaemon = 1; std::shared_ptr hdcDamon = std::make_shared(hTaskInfo); - + if (hdcDamon == nullptr) { + return -1; + } // cmd: hdc erase partition // check - HdcTransferBase::TransferConfig transferConfig {}; - transferConfig.functionName = "erase"; - transferConfig.options = "erase -f "; - transferConfig.options += TEST_PARTITION_NAME; - std::string bufString = SerialStruct::SerializeToString(transferConfig); + std::string bufString = "erase -f "; + bufString += TEST_PARTITION_NAME; hdcDamon->CommandDispatch(CMD_UPDATER_ERASE, reinterpret_cast(bufString.data()), bufString.size()); return 0; } @@ -272,21 +343,24 @@ public: HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); + if (task == nullptr) { + return -1; + } hTaskInfo = task.get(); hTaskInfo->channelId = 2; // 2 channel id hTaskInfo->sessionId = 0; hTaskInfo->runLoop = &loopMain; hTaskInfo->serverOrDaemon = 1; std::shared_ptr hdcDamon = std::make_shared(hTaskInfo); - + if (hdcDamon == nullptr) { + return -1; + } // cmd: hdc format partition // check - HdcTransferBase::TransferConfig transferConfig {}; - transferConfig.functionName = "format"; - transferConfig.options = "format -f "; - transferConfig.options += TEST_PARTITION_NAME; - std::string bufString = SerialStruct::SerializeToString(transferConfig); - hdcDamon->CommandDispatch(CMD_UPDATER_ERASE, reinterpret_cast(bufString.data()), bufString.size()); + std::string bufString = "format -f "; + bufString += TEST_PARTITION_NAME + " -t ext4"; + hdcDamon->CommandDispatch(CMD_UPDATER_FORMAT, reinterpret_cast(bufString.data()), bufString.size()); + return 0; } }; @@ -303,12 +377,24 @@ HWTEST_F(FLashServiceUnitTest, TestDaemonUpdater, TestSize.Level1) EXPECT_EQ(0, test.TestDaemonUpdater()); } +HWTEST_F(FLashServiceUnitTest, TestDoUpdater, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestDoUpdater()); +} + HWTEST_F(FLashServiceUnitTest, TestHdcDaemonFlash, TestSize.Level1) { FLashServiceUnitTest test; EXPECT_EQ(0, test.TestHdcDaemonFlash()); } +HWTEST_F(FLashServiceUnitTest, TestHdcDaemonInvalid, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestHdcDaemonInvalid()); +} + HWTEST_F(FLashServiceUnitTest, TestHdcDaemonErase, TestSize.Level1) { FLashServiceUnitTest test; @@ -336,7 +422,9 @@ HWTEST_F(FLashServiceUnitTest, TestDoFlashPartition, TestSize.Level1) HWTEST_F(FLashServiceUnitTest, TestDoFormatPartition, TestSize.Level1) { FLashServiceUnitTest test; - EXPECT_EQ(0, test.TestDoFormatPartition()); + EXPECT_EQ(0, test.TestDoFormatPartition("data", "ext4")); + EXPECT_EQ(0, test.TestDoFormatPartition("data", "f2fs")); + EXPECT_EQ(0, test.TestDoFormatPartition("boot", "f2fs")); } HWTEST_F(FLashServiceUnitTest, TestDoErasePartition, TestSize.Level1) @@ -345,6 +433,12 @@ HWTEST_F(FLashServiceUnitTest, TestDoErasePartition, TestSize.Level1) EXPECT_EQ(0, test.TestDoErasePartition()); } +HWTEST_F(FLashServiceUnitTest, TestFlashServiceDoResizeParatiton, TestSize.Level1) +{ + FLashServiceUnitTest test; + EXPECT_EQ(0, test.TestFlashServiceDoResizeParatiton()); +} + HWTEST_F(FLashServiceUnitTest, TestFlashServiceDoPrepare, TestSize.Level1) { FLashServiceUnitTest test; @@ -361,7 +455,7 @@ HWTEST_F(FLashServiceUnitTest, TestFlashServiceDoPrepare, TestSize.Level1) EXPECT_EQ(0, test.TestFlashServiceDoPrepare(flashd::UPDATEMOD_ERASE, cmdParam)); cmdParam = "format -f "; - cmdParam += TEST_PARTITION_NAME + " "; + cmdParam += TEST_PARTITION_NAME + " -t ext4"; EXPECT_EQ(0, test.TestFlashServiceDoPrepare(flashd::UPDATEMOD_FORMAT, cmdParam)); EXPECT_EQ(0, test.TestFlashServiceDoPrepare(flashd::UPDATEMOD_MAX, cmdParam)); @@ -382,11 +476,11 @@ HWTEST_F(FLashServiceUnitTest, TestFlashServiceDoFlash, TestSize.Level1) cmdParam += TEST_PARTITION_NAME + " "; EXPECT_EQ(0, test.TestFlashServiceDoFlash(flashd::UPDATEMOD_ERASE, cmdParam)); - cmdParam = "format -f ext4 "; + cmdParam = "format -f -t ext4 "; cmdParam += TEST_PARTITION_NAME + " "; EXPECT_EQ(0, test.TestFlashServiceDoFlash(flashd::UPDATEMOD_FORMAT, cmdParam)); - cmdParam = "format -f f2fs "; + cmdParam = "format -f -t f2fs "; cmdParam += TEST_PARTITION_NAME + " "; EXPECT_EQ(0, test.TestFlashServiceDoFlash(flashd::UPDATEMOD_FORMAT, cmdParam)); diff --git a/test/unittest/package/package_unittest.cpp b/test/unittest/package/package_unittest.cpp index 381c58f6..5031c3e0 100755 --- a/test/unittest/package/package_unittest.cpp +++ b/test/unittest/package/package_unittest.cpp @@ -38,7 +38,7 @@ public: PackageUnitTest() {} ~PackageUnitTest() override {} public: - int TestPackagePack() + int TestPackagePack(int type = PKG_DIGEST_TYPE_SHA256) { int32_t ret; uint32_t updateFileVersion = 1000; @@ -48,7 +48,7 @@ public: pkgInfo.time = strdup("21:23:49"); pkgInfo.productUpdateId = strdup("555.555.100.555"); pkgInfo.entryCount = testFileNames_.size(); - pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; + pkgInfo.digestMethod = type; pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE; pkgInfo.updateFileVersion = updateFileVersion; @@ -74,7 +74,8 @@ public: } std::string packagePath = TEST_PATH_TO; packagePath += testPackageName; - ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(), GetTestPrivateKeyName().c_str()); + ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(), + GetTestPrivateKeyName(pkgInfo.digestMethod).c_str()); EXPECT_EQ(ret, PKG_SUCCESS); for (size_t i = 0; i < testFileNames_.size(); i++) { free(comp[i].componentAddr); @@ -88,13 +89,13 @@ public: return ret; } - int TestPackageUnpack() + int TestPackageUnpack(int type) { pkgManager_ = static_cast(PkgManager::GetPackageInstance()); EXPECT_NE(pkgManager_, nullptr); std::vector components; // 使用上面打包的包进行解析 - int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testPackageName, GetTestCertName(), components); + int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testPackageName, GetTestCertName(type), components); EXPECT_EQ(ret, PKG_SUCCESS); for (size_t i = 0; i < components.size(); i++) { @@ -104,17 +105,18 @@ public: return PKG_SUCCESS; } - int TestZipPkgCompress() + int TestZipPkgCompress(int digestMethod) { - return CreateZipPackage(testFileNames_, TEST_PATH_TO + testZipPackageName, TEST_PATH_FROM); + return CreateZipPackage(testFileNames_, TEST_PATH_TO + testZipPackageName, TEST_PATH_FROM, digestMethod); } - int TestZipPkgDecompress() + int TestZipPkgDecompress(int digestMethod) { pkgManager_ = static_cast(PkgManager::GetPackageInstance()); EXPECT_NE(pkgManager_, nullptr); std::vector components; - int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testZipPackageName, GetTestCertName(), components); + int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testZipPackageName, + GetTestCertName(digestMethod), components); EXPECT_EQ(ret, PKG_SUCCESS); for (size_t i = 0; i < components.size(); i++) { @@ -146,7 +148,8 @@ public: pkgInfo.pkgType = PKG_PACK_TYPE_LZ4; pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; - return pkgManager_->CreatePackage(TEST_PATH_TO + testLz4PackageName, GetTestPrivateKeyName(), &pkgInfo, files); + return pkgManager_->CreatePackage(TEST_PATH_TO + testLz4PackageName, + GetTestPrivateKeyName(pkgInfo.digestMethod), &pkgInfo, files); } int TestLz4PkgCompressBlock() @@ -170,7 +173,8 @@ public: pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; pkgInfo.pkgType = PKG_PACK_TYPE_LZ4; - return pkgManager_->CreatePackage(TEST_PATH_TO + testLz4PackageName, GetTestPrivateKeyName(), &pkgInfo, files); + return pkgManager_->CreatePackage(TEST_PATH_TO + testLz4PackageName, + GetTestPrivateKeyName(pkgInfo.digestMethod), &pkgInfo, files); } int TestLz4PkgDecompress() @@ -178,7 +182,7 @@ public: pkgManager_ = static_cast(PkgManager::GetPackageInstance()); EXPECT_NE(pkgManager_, nullptr); std::vector components; - int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testLz4PackageName, GetTestCertName(), components); + int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testLz4PackageName, GetTestCertName(0), components); EXPECT_EQ(ret, PKG_SUCCESS); for (size_t i = 0; i < components.size(); i++) { @@ -197,7 +201,7 @@ public: std::vector fileNames; fileNames.push_back(testZipPackageName); fileNames.push_back(testPackageName); - ret = CreateZipPackage(fileNames, TEST_PATH_TO + testCombinePkgName, TEST_PATH_TO); + ret = CreateZipPackage(fileNames, TEST_PATH_TO + testCombinePkgName, TEST_PATH_TO, PKG_DIGEST_TYPE_SHA256); EXPECT_EQ(ret, PKG_SUCCESS); return 0; } @@ -208,7 +212,7 @@ public: pkgManager_ = static_cast(PkgManager::GetPackageInstance()); EXPECT_NE(pkgManager_, nullptr); std::vector components; - int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testCombinePkgName, GetTestCertName(), components); + int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testCombinePkgName, GetTestCertName(0), components); EXPECT_EQ(ret, PKG_SUCCESS); for (size_t i = 0; i < components.size(); i++) { @@ -228,30 +232,30 @@ public: std::vector digest(digestSize); BuildFileDigest(*digest.data(), digest.capacity(), TEST_PATH_TO + testPackageName); std::string path = TEST_PATH_TO + testPackageName; - ret = VerifyPackage(path.c_str(), GetTestCertName().c_str(), "", digest.data(), digest.capacity()); + ret = VerifyPackage(path.c_str(), GetTestCertName(0).c_str(), "", digest.data(), digest.capacity()); EXPECT_EQ(0, ret); constexpr uint32_t digestLen = 10; digest[digestLen] = digestValue; - ret = VerifyPackage(path.c_str(), GetTestCertName().c_str(), "", digest.data(), digest.capacity()); + ret = VerifyPackage(path.c_str(), GetTestCertName(0).c_str(), "", digest.data(), digest.capacity()); EXPECT_EQ(PKG_INVALID_SIGNATURE, ret); return 0; } int TestVerifyZipWithCallback() { - int32_t ret = TestVerifyZip(); + int32_t ret = TestVerifyZip(PKG_DIGEST_TYPE_SHA256); EXPECT_EQ(ret, 0); std::string path = GetCurrPath(); path = TEST_PATH_TO + testZipPackageName; - ret = VerifyPackageWithCallback(path.c_str(), GetTestCertName().c_str(), + ret = VerifyPackageWithCallback(path.c_str(), GetTestCertName(0).c_str(), [](int32_t result, uint32_t percent) { PKG_LOGI("current progress: %u\n", percent); }); EXPECT_EQ(PKG_INVALID_PARAM, ret); return 0; } - int TestVerifyZip() + int TestVerifyZip(int digestMethod) { - int32_t ret = TestZipPkgCompress(); + int32_t ret = TestZipPkgCompress(digestMethod); EXPECT_EQ(ret, 0); constexpr size_t digestSize = 32; uint8_t digestValue = 33; @@ -260,10 +264,12 @@ public: path = TEST_PATH_TO + testZipPackageName; std::vector digest(digestSize); BuildFileDigest(*digest.data(), digest.capacity(), path); - ret = VerifyPackage(path.c_str(), GetTestCertName().c_str(), "", digest.data(), digest.capacity()); + ret = VerifyPackage(path.c_str(), GetTestCertName(digestMethod).c_str(), + std::to_string(digestMethod).c_str(), digest.data(), digest.capacity()); EXPECT_EQ(ret, 0); digest[index] = digestValue; - ret = VerifyPackage(path.c_str(), GetTestCertName().c_str(), "", digest.data(), digest.capacity()); + ret = VerifyPackage(path.c_str(), GetTestCertName(0).c_str(), + std::to_string(digestMethod).c_str(), digest.data(), digest.capacity()); EXPECT_EQ(PKG_INVALID_SIGNATURE, ret); return 0; } @@ -279,10 +285,10 @@ public: path = TEST_PATH_TO + testLz4PackageName; std::vector digest(digestSize); BuildFileDigest(*digest.data(), digest.capacity(), path); - ret = VerifyPackage(path.c_str(), GetTestCertName().c_str(), "", digest.data(), digest.capacity()); + ret = VerifyPackage(path.c_str(), GetTestCertName(0).c_str(), "", digest.data(), digest.capacity()); EXPECT_EQ(0, ret); digest[index] = digestValue; - ret = VerifyPackage(path.c_str(), GetTestCertName().c_str(), "", digest.data(), digest.capacity()); + ret = VerifyPackage(path.c_str(), GetTestCertName(0).c_str(), "", digest.data(), digest.capacity()); EXPECT_EQ(PKG_INVALID_SIGNATURE, ret); return 0; } @@ -309,7 +315,8 @@ public: } std::string packagePath = TEST_PATH_TO; packagePath += testPackageName; - int32_t ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(), GetTestPrivateKeyName().c_str()); + int32_t ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(), + GetTestPrivateKeyName(pkgInfo.digestMethod).c_str()); for (size_t i = 0; i < testFileNames_.size(); i++) { free(comp[i].componentAddr); free(comp[i].filePath); @@ -319,7 +326,7 @@ public: uint8_t digest[digestSize] = {0}; ret = BuildFileDigest(*digest, sizeof(digest), packagePath); EXPECT_EQ(ret, PKG_SUCCESS); - ret = VerifyPackage(packagePath.c_str(), GetTestCertName().c_str(), "", digest, digestSize); + ret = VerifyPackage(packagePath.c_str(), GetTestCertName(0).c_str(), "", digest, digestSize); return ret; } @@ -355,30 +362,30 @@ public: std::vector digest(digestSize); ret = BuildFileDigest(*digest.data(), digest.size(), packagePath.c_str()); EXPECT_EQ(ret, PKG_SUCCESS); - return VerifyPackage(packagePath.c_str(), GetTestCertName().c_str(), "", digest.data(), digest.size()); + return VerifyPackage(packagePath.c_str(), GetTestCertName(0).c_str(), "", digest.data(), digest.size()); } int TestInvalidCreatePackage() const { ComponentInfoExt compInfo; uint8_t pkgType = 5; - int ret = CreatePackage(nullptr, &compInfo, nullptr, GetTestPrivateKeyName().c_str()); + int ret = CreatePackage(nullptr, &compInfo, nullptr, GetTestPrivateKeyName(0).c_str()); EXPECT_EQ(ret, PKG_INVALID_PARAM); UpgradePkgInfoExt pkgInfoExt; pkgInfoExt.pkgType = pkgType; - ret = CreatePackage(&pkgInfoExt, &compInfo, nullptr, GetTestPrivateKeyName().c_str()); + ret = CreatePackage(&pkgInfoExt, &compInfo, nullptr, GetTestPrivateKeyName(0).c_str()); EXPECT_EQ(ret, PKG_INVALID_PARAM); constexpr uint32_t digestLen = 32; - ret = VerifyPackage(nullptr, GetTestCertName().c_str(), nullptr, nullptr, digestLen); + ret = VerifyPackage(nullptr, GetTestCertName(0).c_str(), nullptr, nullptr, digestLen); EXPECT_EQ(ret, PKG_INVALID_PARAM); // 无效的类型 std::string packagePath = TEST_PATH_TO; packagePath += testPackageName; pkgInfoExt.pkgType = pkgType; - ret = CreatePackage(&pkgInfoExt, &compInfo, packagePath.c_str(), GetTestPrivateKeyName().c_str()); + ret = CreatePackage(&pkgInfoExt, &compInfo, packagePath.c_str(), GetTestPrivateKeyName(0).c_str()); EXPECT_EQ(ret, PKG_INVALID_PARAM); return 0; } @@ -403,7 +410,8 @@ public: pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; pkgInfo.pkgType = PKG_PACK_TYPE_GZIP; - return pkgManager_->CreatePackage(TEST_PATH_TO + testGZipPackageName, GetTestPrivateKeyName(), &pkgInfo, files); + return pkgManager_->CreatePackage(TEST_PATH_TO + testGZipPackageName, + GetTestPrivateKeyName(pkgInfo.digestMethod), &pkgInfo, files); } int TestGZipPkgDecompress(const std::string& gzipPackageName) @@ -411,7 +419,7 @@ public: pkgManager_ = static_cast(PkgManager::GetPackageInstance()); EXPECT_NE(nullptr, pkgManager_); std::vector components; - int32_t ret = pkgManager_->LoadPackage(gzipPackageName, GetTestCertName(), components); + int32_t ret = pkgManager_->LoadPackage(gzipPackageName, GetTestCertName(0), components); EXPECT_EQ(ret, PKG_SUCCESS); for (size_t i = 0; i < components.size(); i++) { @@ -440,7 +448,7 @@ public: pkgManager_ = static_cast(PkgManager::GetPackageInstance()); EXPECT_NE(nullptr, pkgManager_); std::vector fileIds; - int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testPackageName, GetTestCertName(), fileIds); + int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testPackageName, GetTestCertName(0), fileIds); EXPECT_EQ(0, ret); // 在load其中的一个zip包 PkgManager::StreamPtr outStream = nullptr; @@ -451,7 +459,7 @@ public: EXPECT_EQ(ret, 0); pkgManager_->ClosePkgStream(outStream); std::vector secondFileIds; - ret = pkgManager_->LoadPackage(TEST_PATH_TO + secondFile, GetTestCertName(), secondFileIds); + ret = pkgManager_->LoadPackage(TEST_PATH_TO + secondFile, GetTestCertName(0), secondFileIds); EXPECT_EQ(0, ret); if (secondFileIds.size() != 1) { EXPECT_EQ(1, ret); @@ -563,15 +571,29 @@ public: HWTEST_F(PackageUnitTest, TestPackage, TestSize.Level1) { PackageUnitTest test; - EXPECT_EQ(0, test.TestPackagePack()); - EXPECT_EQ(0, test.TestPackageUnpack()); + EXPECT_EQ(0, test.TestPackagePack(PKG_DIGEST_TYPE_SHA256)); + EXPECT_EQ(0, test.TestPackageUnpack(PKG_DIGEST_TYPE_SHA256)); +} + +HWTEST_F(PackageUnitTest, TestPackage384, TestSize.Level1) +{ + PackageUnitTest test; + EXPECT_EQ(0, test.TestPackagePack(PKG_DIGEST_TYPE_SHA384)); + EXPECT_EQ(0, test.TestPackageUnpack(PKG_DIGEST_TYPE_SHA384)); } HWTEST_F(PackageUnitTest, TestZipPackage, TestSize.Level1) { PackageUnitTest test; - EXPECT_EQ(0, test.TestZipPkgCompress()); - EXPECT_EQ(0, test.TestZipPkgDecompress()); + EXPECT_EQ(0, test.TestZipPkgCompress(PKG_DIGEST_TYPE_SHA256)); + EXPECT_EQ(0, test.TestZipPkgDecompress(PKG_DIGEST_TYPE_SHA256)); +} + +HWTEST_F(PackageUnitTest, TestZipPackage384, TestSize.Level1) +{ + PackageUnitTest test; + EXPECT_EQ(0, test.TestZipPkgCompress(PKG_DIGEST_TYPE_SHA384)); + EXPECT_EQ(0, test.TestZipPkgDecompress(PKG_DIGEST_TYPE_SHA384)); } HWTEST_F(PackageUnitTest, TestLz4Package, TestSize.Level1) @@ -609,7 +631,8 @@ HWTEST_F(PackageUnitTest, TestVerifyZipWithCallback, TestSize.Level1) HWTEST_F(PackageUnitTest, TestVerifyZip, TestSize.Level1) { PackageUnitTest test; - EXPECT_EQ(0, test.TestVerifyZip()); + EXPECT_EQ(0, test.TestVerifyZip(PKG_DIGEST_TYPE_SHA384)); + EXPECT_EQ(0, test.TestVerifyZip(PKG_DIGEST_TYPE_SHA256)); } HWTEST_F(PackageUnitTest, TestVerifyLz4, TestSize.Level1) { diff --git a/test/unittest/package/pkg_algo_unittest.cpp b/test/unittest/package/pkg_algo_unittest.cpp index fbab4b1c..43836721 100755 --- a/test/unittest/package/pkg_algo_unittest.cpp +++ b/test/unittest/package/pkg_algo_unittest.cpp @@ -131,7 +131,7 @@ public: return 0; } - int TestSignVerify(int8_t signMethod, std::string privateKey, std::string certName) + int TestSignVerify(int8_t signMethod, std::string privateKey, std::string certName, uint8_t hashType) { PkgBuffer digest(DIGEST_LEN); std::string filePath = TEST_PATH_FROM; @@ -141,7 +141,7 @@ public: // 签名 filePath = TEST_PATH_FROM + privateKey; SignAlgorithm::SignAlgorithmPtr algorithm = PkgAlgorithmFactory::GetSignAlgorithm(filePath, - signMethod, PKG_DIGEST_TYPE_SHA256); + signMethod, hashType); EXPECT_NE(nullptr, algorithm); std::vector signature; size_t signLen = 0; @@ -152,7 +152,7 @@ public: EXPECT_EQ(ret, PKG_INVALID_SIGNATURE); filePath = TEST_PATH_FROM + certName; - algorithm = PkgAlgorithmFactory::GetVerifyAlgorithm(filePath, PKG_DIGEST_TYPE_SHA256); + algorithm = PkgAlgorithmFactory::GetVerifyAlgorithm(filePath, hashType); // 验证 ret = algorithm->SignBuffer(digest, signature, signLen); EXPECT_EQ(ret, PKG_INVALID_SIGNATURE); @@ -229,13 +229,22 @@ HWTEST_F(PkgAlgoUnitTest, TestHash256Digest, TestSize.Level1) HWTEST_F(PkgAlgoUnitTest, TestRsaSignVerify, TestSize.Level1) { PkgAlgoUnitTest test; - EXPECT_EQ(0, test.TestSignVerify(PKG_SIGN_METHOD_RSA, "rsa_private_key2048.pem", "signing_cert.crt")); + EXPECT_EQ(0, test.TestSignVerify(PKG_SIGN_METHOD_RSA, + "rsa_private_key2048.pem", "signing_cert.crt", PKG_DIGEST_TYPE_SHA256)); +} + +HWTEST_F(PkgAlgoUnitTest, TestRsaSignVerify384, TestSize.Level1) +{ + PkgAlgoUnitTest test; + EXPECT_EQ(0, test.TestSignVerify(PKG_SIGN_METHOD_RSA, + "rsa_private_key384.pem", "signing_cert384.crt", PKG_DIGEST_TYPE_SHA384)); } HWTEST_F(PkgAlgoUnitTest, TestEccSignVerify, TestSize.Level1) { PkgAlgoUnitTest test; - EXPECT_EQ(0, test.TestSignVerify(PKG_SIGN_METHOD_ECDSA, "ecc/prime256v1-key.pem", "ecc/signing_cert.crt")); + EXPECT_EQ(0, test.TestSignVerify(PKG_SIGN_METHOD_ECDSA, + "ecc/prime256v1-key.pem", "ecc/signing_cert.crt", PKG_DIGEST_TYPE_SHA256)); } HWTEST_F(PkgAlgoUnitTest, TestEccUserPackage, TestSize.Level1) diff --git a/test/unittest/package/pkg_manager_unittest.cpp b/test/unittest/package/pkg_manager_unittest.cpp index b7143e9f..dcbf120d 100755 --- a/test/unittest/package/pkg_manager_unittest.cpp +++ b/test/unittest/package/pkg_manager_unittest.cpp @@ -137,7 +137,7 @@ public: GetUpgradePkgInfo(pkgInfo, files); std::string packagePath = TEST_PATH_TO; packagePath += testPackageName; - int32_t ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(), &pkgInfo.pkgInfo, files); + int32_t ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(0), &pkgInfo.pkgInfo, files); EXPECT_EQ(ret, PKG_SUCCESS); return 0; } @@ -153,7 +153,7 @@ public: // 修改成错误的路径 files[0].first = "sssssssssss"; - int32_t ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(), &pkgInfo.pkgInfo, files); + int32_t ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(0), &pkgInfo.pkgInfo, files); EXPECT_EQ(ret, PKG_INVALID_FILE); return 0; } @@ -164,7 +164,7 @@ public: std::vector> files; std::string packagePath = TEST_PATH_TO; packagePath += testPackageName; - int32_t ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(), nullptr, files); + int32_t ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(0), nullptr, files); EXPECT_EQ(ret, PKG_INVALID_PARAM); return 0; } @@ -177,7 +177,7 @@ public: } PKG_LOGI("\n\n ************* TestCombinePkgUNpack %s \r\n", testCombinePkgName.c_str()); std::vector components; - int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testCombinePkgName, GetTestCertName(), components); + int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testCombinePkgName, GetTestCertName(0), components); if (ret != PKG_SUCCESS) { PKG_LOGE("LoadPackage fail ret:%d", ret); return ret; @@ -258,7 +258,7 @@ public: } PKG_LOGI("\n\n ************* TestCombinePkgUNpack %s \r\n", testCombinePkgName.c_str()); std::vector components; - int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testCombinePkgName, GetTestCertName(), components); + int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testCombinePkgName, GetTestCertName(0), components); if (ret != PKG_SUCCESS) { PKG_LOGI("LoadPackage fail ret:%d", ret); return ret; @@ -297,7 +297,7 @@ public: } PKG_LOGI("\n\n ************* TestCombinePkgUNpack %s \r\n", testCombinePkgName.c_str()); std::vector components; - int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testCombinePkgName, GetTestCertName(), components); + int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testCombinePkgName, GetTestCertName(0), components); if (ret != PKG_SUCCESS) { PKG_LOGI("LoadPackage fail ret:%d", ret); return ret; @@ -404,7 +404,7 @@ public: std::string packagePath = TEST_PATH_TO; packagePath += testPackageName; files.push_back(std::pair("/qqqqqq", info)); - int ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(), &pkgInfo.pkgInfo, files); + int ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(0), &pkgInfo.pkgInfo, files); EXPECT_EQ(ret, PKG_INVALID_FILE); return 0; } @@ -418,7 +418,7 @@ public: packagePath += testPackageName; uint8_t signMethodIndex = 10; pkgInfo.pkgInfo.signMethod = PKG_SIGN_METHOD_RSA + signMethodIndex; - int ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(), &pkgInfo.pkgInfo, files); + int ret = pkgManager_->CreatePackage(packagePath, GetTestPrivateKeyName(0), &pkgInfo.pkgInfo, files); EXPECT_NE(ret, 0); return 0; } @@ -440,7 +440,7 @@ public: pkgInfo.pkgType = PKG_PACK_TYPE_GZIP; std::string fileName = TEST_PATH_TO; fileName += testGZipPackageName; - int ret = pkgManager_->CreatePackage(fileName, GetTestPrivateKeyName(), &pkgInfo, files); + int ret = pkgManager_->CreatePackage(fileName, GetTestPrivateKeyName(0), &pkgInfo, files); EXPECT_EQ(ret, PKG_INVALID_FILE); return 0; } @@ -463,7 +463,7 @@ public: pkgInfo.pkgType = PKG_PACK_TYPE_GZIP + pkgTypeIndex; std::string fileName = TEST_PATH_TO; fileName += testGZipPackageName; - int ret = pkgManager_->CreatePackage(fileName, GetTestPrivateKeyName(), &pkgInfo, files); + int ret = pkgManager_->CreatePackage(fileName, GetTestPrivateKeyName(0), &pkgInfo, files); EXPECT_EQ(ret, PKG_INVALID_FILE); return 0; } @@ -487,7 +487,7 @@ public: pkgInfo.pkgType = PKG_PACK_TYPE_ZIP; std::string fileName = TEST_PATH_TO; fileName += testZipPackageName; - int ret = pkgManager_->CreatePackage(fileName, GetTestPrivateKeyName(), &pkgInfo, files); + int ret = pkgManager_->CreatePackage(fileName, GetTestPrivateKeyName(0), &pkgInfo, files); EXPECT_EQ(ret, PKG_INVALID_FILE); return 0; } @@ -499,7 +499,7 @@ public: std::vector components; std::string fileName = TEST_PATH_TO; fileName += "testZipPackageName.aaa"; - int32_t ret = pkgManager_->LoadPackage(fileName, GetTestCertName(), components); + int32_t ret = pkgManager_->LoadPackage(fileName, GetTestCertName(0), components); EXPECT_EQ(ret, PKG_INVALID_FILE); return 0; } diff --git a/test/unittest/package/pkg_package_unittest.cpp b/test/unittest/package/pkg_package_unittest.cpp index bdd92603..2880e5cd 100755 --- a/test/unittest/package/pkg_package_unittest.cpp +++ b/test/unittest/package/pkg_package_unittest.cpp @@ -38,8 +38,6 @@ namespace { constexpr uint32_t MAX_FILE_NAME = 256; constexpr uint32_t CENTRAL_SIGNATURE = 0x02014b50; constexpr uint32_t END_CENTRAL_SIGNATURE = 0x06054b50; -constexpr uint32_t ZIP_NODE_ID = 100; -constexpr size_t GIANT_NUMBER = 100000; class TestFile : public PkgFile { public: @@ -122,13 +120,14 @@ public: EXPECT_NE(pkgManager_, nullptr); PkgManager::StreamPtr stream = nullptr; std::string packagePath = TEST_PATH_TO; + uint32_t zipNodeId = 100; packagePath += testPackageName; pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); EXPECT_NE(stream, nullptr); std::unique_ptr file = std::make_unique(pkgManager_, PkgStreamImpl::ConvertPkgStream(stream)); EXPECT_NE(file, nullptr); - std::unique_ptr entry = std::make_unique(file.get(), ZIP_NODE_ID); + std::unique_ptr entry = std::make_unique(file.get(), zipNodeId); EXPECT_NE(entry, nullptr); string name = "TestBigZip"; @@ -162,7 +161,8 @@ public: EXPECT_EQ(ret, 0); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length(), 1); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetHalfWord, offset4Words); - size_t size = UINT_MAX + GIANT_NUMBER; + size_t giantNumber = 100000; + size_t size = UINT_MAX + giantNumber; WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetWord, size); WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offset3Words, size); size_t decodeLen = 0; diff --git a/test/unittest/package/pkg_test.h b/test/unittest/package/pkg_test.h index 16a72a4d..e650d298 100755 --- a/test/unittest/package/pkg_test.h +++ b/test/unittest/package/pkg_test.h @@ -142,7 +142,7 @@ protected: } int CreateZipPackage(const std::vector &testFileNames, - const std::string packageName, const std::string &base) + const std::string packageName, const std::string &base, int digestMethod) { PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); EXPECT_NE(pkgManager, nullptr); @@ -159,9 +159,9 @@ protected: PkgInfo pkgInfo; pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; - pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; + pkgInfo.digestMethod = digestMethod; pkgInfo.pkgType = PKG_PACK_TYPE_ZIP; - int32_t ret = pkgManager->CreatePackage(packageName, GetTestPrivateKeyName(), &pkgInfo, files); + int32_t ret = pkgManager->CreatePackage(packageName, GetTestPrivateKeyName(digestMethod), &pkgInfo, files); EXPECT_EQ(ret, 0); return ret; } diff --git a/test/unittest/test_data/src/rsa_private_key384.pem b/test/unittest/test_data/src/rsa_private_key384.pem new file mode 100755 index 00000000..9ade6de3 --- /dev/null +++ b/test/unittest/test_data/src/rsa_private_key384.pem @@ -0,0 +1,39 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIG5QIBAAKCAYEA0mDyEBQc9A/z+la197GMMhFAkL/g1TNnGo5cIm+dclLom4sY +3MDTtxf/GfuNeVdGOIimUb2Zu1XqZaV+HSRh7bggqfwZ9RMgJkHlMpm8JFG9y0Nj +lon+HQdme4jU+p1r4ZycWw2P16PwTBv2pGhd0/yIas909H97nIldyPsfDiO4gxoQ +uVMpeVEK+32j0bFpelZzgn3sQdyXKRNFS8wCt64p3TMFVO1HZaGt+e7UQV6dqQgj +QOUwiEKMdgGI+Day9OGYu0Y5S13adltQKGbwE8J+KNNtTuzWaVZXJzGcNykDSZVi +r/pbVqhbMEPnpsMJ4zMwZY/bL3TYqwG2BbmRb+NJej0Uh7LurHNScxSP0/qEzbkm +tnVtTvIrvVlbLc6r2TebU4fDhFIi3obRGCBBar6epZM7Rz7e0v45MYlWEEyJcUqO +s0zlqccveBO+J4He3bUiHI0fdG2oAfYetgT3Mo/EwH6QEVDcUYazuJTnihDT478k +obZqTwwxRrIOECBrAgMBAAECggGBALR65M80Yg5jLTyDbQJ8t7gwIsLLSbe9rGMU +5CfKtzjftZvS/dZMOpTlqj0BGEKTw7M2T/DqBlu3fioLiqC3mKeWgbcyhpY//SG1 +AEqjpstFsNwTCPmZkn4W3i12mrgRmv5nG5/lh5RImRrCFpq+ylfVWra/GSezwjjt +g56rCN5ZeK5ICzbiCD+CbjiIdaSsXb/NMLUvECMEek2LsbQv5djsOhAA+D7+fHTM ++nLjGAaog/sB9zRyKmuLI/MMqBPA38GT80ufzA9wqjr08luTt+LBhEOWJgCwvn1U +O56SMXcCvBW2eVlXzh4nDTwipihj9+nBn9UXMn/l39tKLupIz1oQEbA7+/1CI3wA +gXK8BkBRbYuulGNZTBBZB9gq8HYy9zUl/RwNqE2p3E0nHhKlQtTPdUVq+z822Q/E +TJMOHzQzBJqj6oii5rRPGmjICXFFfgOVydBo0dYq+/2mMxDjGzpeDOaHQgq06tsj +IesCTyfqTKRrWuYW8IRl34mxoX6OYQKBwQDoKeOjRDkBBrkTRwfMHIYSuBlgAunr +0JG6rtZ3wYSKCweS/OQbviV7EpoVLCAmqjgPLbIIBmxK2+xfH8a/83SesW/Jwd2C +1umJPVu+N8Kwpc+XNeN3Pjwp3DSCsXBNb1rsOBw/vsolKWM5KxqG7qUa/CVtbJO+ +/5r87Rbw6A+cldNR383QeBKsPhdZYD5eh8g5btavV3knfG50TwfL0uNxKfu0l9Oq +jR9C+BC4DsZMBLBlUz/VrAtux8y5nsytibsCgcEA5/p36b7zYqD+2PHviqEVf007 +P7CqL8AZge7fDHi/hgMzSMIt+jgfvO+beNPcadqAeJ26/BZJZpL1lsU7+tUZYB3B +/h3TZp4/JVnT9Y24QB9y1aCLa+vZ60ItaGwOlltGhojIG3/YtslgG80e/4Ob1nMM +y/tSfUlzD2jVUqmUSNtpcTScAs14FAsYv7HRZskNfT11nKuVW5h5zVDmxb27FkK7 +m2lRPWAVHgwrvdAD9F0oUAAoH+Y5SXujYkz/3MERAoHBANIXJiJW2GbvWIfzXUD+ +Bu3ln0DdIiX9pgKTuQzCGFh7Rq1jIGFinrRSzxCdz7JtkzFZHqRYe6L6hVpHfSmy +/DOnSgv/3Z5LMSa6Wc021H3abpLddywvK26OEQ67126beGIPHLEqy+75Fwti0CyO +xOY4iv4MpV7QG8cKHhp/RbFje8m5h5xBLFSmE6cTix0sLqqafLhLph1vYtzpr5pp +Ct0bKuXwBuFtt3540VheNmAQVjg7L6cCe44STFclNv9LhQKBwQDiwsz6+gSyMcxM +x1qv+byo3xb+sDP8T1zfzV/Nsi8N0g0Mn3wQL1Ke/t3MY9T+yG9y+ERy7Vo84YUe +J5j1HeAbO5uJSyB+HEx/t2phi3JDhDpdpv0Ctt8jgGIgxBgSVBEBq61obDWsn/bJ +1l3pyX3JSFeHAhpljCnkM0br8gaYnZpZ5eJnPvCVLy+3GxwlzHzaIvzX9EYg7lCK +Kf4b59Z88Siwx2d5hnW+FImhlzh2Y6XnZe/TFtqDAU/55GjsIvECgcAXmPO1hSlz +nE1Pw5X7AJiF/PjeEYs210Ac1df01mcOa+tDBx+9+m05RjlpZ6bI8AO9606suViB +yPf9DYet+d4cI1FYqQl4B3qXdZl1upYqv4dsLxOztzMIYi7reg0YXVpj2Rhwybzd +onKc9j8KNb55TB1JKHqwvJBhgRpTB6ucxzJYLXal60O6R8Png56S51O3rz3qWh9J +Z48aTa06SIHhDyzDslYddTQ2QpRqWbkRcgOkUY+ZfCpDXjp4YU03Yzk= +-----END RSA PRIVATE KEY----- diff --git a/test/unittest/test_data/src/signing_cert384.crt b/test/unittest/test_data/src/signing_cert384.crt new file mode 100755 index 00000000..73e145b0 --- /dev/null +++ b/test/unittest/test_data/src/signing_cert384.crt @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEazCCAtOgAwIBAgIUWG5lzXTJz5lQ1X2BClMyzltqBhEwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTEwMjgxMTI2MjVaFw0yMjEw +MjgxMTI2MjVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggGiMA0GCSqGSIb3DQEB +AQUAA4IBjwAwggGKAoIBgQDSYPIQFBz0D/P6VrX3sYwyEUCQv+DVM2cajlwib51y +UuibixjcwNO3F/8Z+415V0Y4iKZRvZm7VeplpX4dJGHtuCCp/Bn1EyAmQeUymbwk +Ub3LQ2OWif4dB2Z7iNT6nWvhnJxbDY/Xo/BMG/akaF3T/Ihqz3T0f3uciV3I+x8O +I7iDGhC5Uyl5UQr7faPRsWl6VnOCfexB3JcpE0VLzAK3rindMwVU7Udloa357tRB +Xp2pCCNA5TCIQox2AYj4NrL04Zi7RjlLXdp2W1AoZvATwn4o021O7NZpVlcnMZw3 +KQNJlWKv+ltWqFswQ+emwwnjMzBlj9svdNirAbYFuZFv40l6PRSHsu6sc1JzFI/T ++oTNuSa2dW1O8iu9WVstzqvZN5tTh8OEUiLehtEYIEFqvp6lkztHPt7S/jkxiVYQ +TIlxSo6zTOWpxy94E74ngd7dtSIcjR90bagB9h62BPcyj8TAfpARUNxRhrO4lOeK +ENPjvyShtmpPDDFGsg4QIGsCAwEAAaNTMFEwHQYDVR0OBBYEFMsre/vRH2jpNO5p +K2bpd6a2vxZMMB8GA1UdIwQYMBaAFMsre/vRH2jpNO5pK2bpd6a2vxZMMA8GA1Ud +EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggGBAKSsEIKEy+EDSUT6yoyR8PxK +omQh7BjoLnpBfDXOJZedBKvIyzFh3I5v93xvLknfPWqKrEwnjQorqfDKa6rIaj/o +UjhPFbzBdrB/EF/IYX1+g1t+fxFQLnu0twRr4F3PK/owno3bwE4A09ZBLub0lNws +NYacSTbrmMNaYMZfqhKWzNMkh+9ICx0bxmtRpBJlVyj6agQ9QQQoTz66qsTexe5e +0H4mSkJ0fIQG53jeHPMeOVb2A9Z558OtzlSiXz7H3LX1ca2i6Hn9rjH1axM6wChj +qeaYI9tVXDpXqT/O6tsMFzJ9Lksq3deguaIHx93kCSFsKVvEpYa3SeHcXnA48AaD +NwxS1fKhD/KEhFtBQ8sq6sPzY51hUJirF+pfRk9VBvQ+E6cGVDOgoDn79tPWjFN9 +KI9388+kVxYzQ4OuoxZC7HvrJUsHYZXDgtN7cp5vKcM9Y0rzkUAQh2BddBClAMHP +2LK6qOq0eMjnkeSl7L6f96B7/8ZW3mBT4CDaqcdYvA== +-----END CERTIFICATE----- diff --git a/test/unittest/test_data/updater/test.img b/test/unittest/test_data/updater/test.img new file mode 100755 index 00000000..ab7bd1d2 --- /dev/null +++ b/test/unittest/test_data/updater/test.img @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + + test flashd \ No newline at end of file diff --git a/test/unittest/test_data/updater/updater.zip b/test/unittest/test_data/updater/updater.zip index 0ecd1ceb..eeae4e4b 100755 --- a/test/unittest/test_data/updater/updater.zip +++ b/test/unittest/test_data/updater/updater.zip @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14357f75170e22c61470c2cd0fe73ee4f4b1a3396ac5d386433e76c0e54d0cd9 -size 13387850 +oid sha256:ab06b6f2a1dbb8563f7da65e79a70a6550620428f7704cca6159e56481d4d1c1 +size 1785615 diff --git a/test/unittest/unittest_comm.h b/test/unittest/unittest_comm.h index 2c396bd0..5f75ad3b 100755 --- a/test/unittest/unittest_comm.h +++ b/test/unittest/unittest_comm.h @@ -23,21 +23,30 @@ #include #include +#include "package/package.h" + const std::string TEST_PATH_FROM = "/data/updater/src/"; const std::string TEST_PATH_TO = "/data/updater/dst/"; -inline std::string GetTestPrivateKeyName() +inline std::string GetTestPrivateKeyName(int type = 0) { std::string name = TEST_PATH_FROM; - name += "rsa_private_key2048.pem"; + if (type != PKG_DIGEST_TYPE_SHA384) { + name += "rsa_private_key2048.pem"; + } else { + name += "rsa_private_key384.pem"; + } return name; } -inline std::string GetTestCertName() +inline std::string GetTestCertName(int type = 0) { std::string name = TEST_PATH_FROM; - name += "signing_cert.crt"; + if (type != PKG_DIGEST_TYPE_SHA384) { + name += "signing_cert.crt"; + } else { + name += "signing_cert384.crt"; + } return name; } - #endif // UNITTEST_COMM diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index 65975e54..770adb21 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -112,25 +112,26 @@ protected: { int32_t ret; int32_t updateFileVersion = 1000; - int fileNameIndex = 3; - uint8_t componentType = 22; + PKG_LOGI("\n\n ************* CreatePackageBin %s \r\n", testPackageName.c_str()); UpgradePkgInfoExt pkgInfo; - ComponentInfoExt *comp = (ComponentInfoExt*)malloc( - sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); - if (comp == nullptr) { - return -1; - } // C API, Cannot use c++ string class. pkgInfo.softwareVersion = strdup("100.100.100.100"); pkgInfo.date = strdup("2021-02-02"); pkgInfo.time = strdup("21:23:49"); pkgInfo.productUpdateId = strdup("555.555.100.555"); + int fileNameIndex = 3; + uint8_t componentType = 22; pkgInfo.entryCount = testFileNames_.size() + fileNameIndex; pkgInfo.updateFileVersion = updateFileVersion; pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE; + ComponentInfoExt *comp = (ComponentInfoExt*)malloc( + sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); + if (comp == nullptr) { + return -1; + } for (size_t i = 0; i < testFileNames_.size(); i++) { BuildCompnentInfo(comp[i], testFileNames_[i], testFileNames_[i], componentType); } diff --git a/test/unittest/updater_main_test/updater_main_unittest.cpp b/test/unittest/updater_main_test/updater_main_unittest.cpp index a3e33c78..743278c8 100755 --- a/test/unittest/updater_main_test/updater_main_unittest.cpp +++ b/test/unittest/updater_main_test/updater_main_unittest.cpp @@ -56,7 +56,7 @@ void UpdaterMainUnitTest::SetUpTestCase(void) if (MountForPath("/data") != 0) { cout << "MountForPath failed" << endl; } - PostUpdater(); + PostUpdater(true); } // end @@ -89,7 +89,7 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_001, TestSize.Level1) std::vector args = ParseParams(argc, argv); EXPECT_EQ(args.size(), static_cast(argc)); - PostUpdater(); + PostUpdater(true); delete argv[0]; delete []argv; } @@ -106,7 +106,7 @@ HWTEST_F(UpdaterMainUnitTest, updater_main_test_002, TestSize.Level1) int fRet = FactoryReset(USER_WIPE_DATA, "/misc/factory_test"); EXPECT_EQ(fRet, 0); - PostUpdater(); + PostUpdater(true); } HWTEST_F(UpdaterMainUnitTest, updater_main_test_003, TestSize.Level1) -- Gitee From c5efa00b31e8aec4777aaeeab79ab4b68ea99f19 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Fri, 5 Nov 2021 16:26:52 +0800 Subject: [PATCH 44/94] fix codestyle Signed-off-by: xionglei6 --- services/diffpatch/diff/blocks_diff.cpp | 4 ++-- .../applypatch_test/imagepatch_unittest.h | 4 +--- test/unittest/package/pkg_package_unittest.cpp | 7 ++++--- .../updater_binary/updater_binary_unittest.cpp | 15 +++++++-------- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/services/diffpatch/diff/blocks_diff.cpp b/services/diffpatch/diff/blocks_diff.cpp index d579dbd9..2a68f28c 100644 --- a/services/diffpatch/diff/blocks_diff.cpp +++ b/services/diffpatch/diff/blocks_diff.cpp @@ -237,7 +237,7 @@ void BlocksDiff::ComputeLength(const BlockBuffer &newInfo, int64_t i = 0; int64_t s = 0; int64_t tmp = 0; - for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length)); ) { + for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length));) { if (oldInfo.buffer[lastPos_ + i] == newInfo.buffer[lastScan_ + i]) { s++; } @@ -413,7 +413,7 @@ void SuffixArray::Init(const BlockBuffer &oldInfo) DataType len = 0; for (h = 1; suffixArray_[0] != -(static_cast(oldInfo.length) + 1); h += h) { len = 0; - for (i = 0; i < (static_cast(oldInfo.length) + 1); ) { + for (i = 0; i < (static_cast(oldInfo.length) + 1);) { if (suffixArray_[i] < 0) { len -= suffixArray_[i]; i -= suffixArray_[i]; diff --git a/test/unittest/applypatch_test/imagepatch_unittest.h b/test/unittest/applypatch_test/imagepatch_unittest.h index 6da5f553..e4cdc358 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.h +++ b/test/unittest/applypatch_test/imagepatch_unittest.h @@ -77,9 +77,7 @@ public: int fd = open(target.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY, mode); EXPECT_GE(fd, 0); BlockSet targetBlk; - targetBlk.ParserAndInsert({ - "2", "0", "1" - }); + targetBlk.ParserAndInsert({"2", "0", "1"}); std::unique_ptr writer = std::make_unique(fd, targetBlk); std::vector empty; int32_t ret = updatepatch::UpdatePatch::ApplyImagePatch(param, empty, diff --git a/test/unittest/package/pkg_package_unittest.cpp b/test/unittest/package/pkg_package_unittest.cpp index 2880e5cd..919e0fe6 100755 --- a/test/unittest/package/pkg_package_unittest.cpp +++ b/test/unittest/package/pkg_package_unittest.cpp @@ -38,6 +38,8 @@ namespace { constexpr uint32_t MAX_FILE_NAME = 256; constexpr uint32_t CENTRAL_SIGNATURE = 0x02014b50; constexpr uint32_t END_CENTRAL_SIGNATURE = 0x06054b50; +constexpr uint32_t ZIP_NODE_ID = 100; +constexpr size_t GIANT_NUMBER = 100000; class TestFile : public PkgFile { public: @@ -127,7 +129,7 @@ public: std::unique_ptr file = std::make_unique(pkgManager_, PkgStreamImpl::ConvertPkgStream(stream)); EXPECT_NE(file, nullptr); - std::unique_ptr entry = std::make_unique(file.get(), zipNodeId); + std::unique_ptr entry = std::make_unique(file.get(), ZIP_NODE_ID); EXPECT_NE(entry, nullptr); string name = "TestBigZip"; @@ -161,8 +163,7 @@ public: EXPECT_EQ(ret, 0); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length(), 1); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetHalfWord, offset4Words); - size_t giantNumber = 100000; - size_t size = UINT_MAX + giantNumber; + size_t size = UINT_MAX + GIANT_NUMBER; WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetWord, size); WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offset3Words, size); size_t decodeLen = 0; diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index 770adb21..65975e54 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -112,26 +112,25 @@ protected: { int32_t ret; int32_t updateFileVersion = 1000; - PKG_LOGI("\n\n ************* CreatePackageBin %s \r\n", testPackageName.c_str()); + int fileNameIndex = 3; + uint8_t componentType = 22; UpgradePkgInfoExt pkgInfo; + ComponentInfoExt *comp = (ComponentInfoExt*)malloc( + sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); + if (comp == nullptr) { + return -1; + } // C API, Cannot use c++ string class. pkgInfo.softwareVersion = strdup("100.100.100.100"); pkgInfo.date = strdup("2021-02-02"); pkgInfo.time = strdup("21:23:49"); pkgInfo.productUpdateId = strdup("555.555.100.555"); - int fileNameIndex = 3; - uint8_t componentType = 22; pkgInfo.entryCount = testFileNames_.size() + fileNameIndex; pkgInfo.updateFileVersion = updateFileVersion; pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE; - ComponentInfoExt *comp = (ComponentInfoExt*)malloc( - sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); - if (comp == nullptr) { - return -1; - } for (size_t i = 0; i < testFileNames_.size(); i++) { BuildCompnentInfo(comp[i], testFileNames_[i], testFileNames_[i], componentType); } -- Gitee From 9887b959d587b2d87a8a3c8ee43adb973f11db50 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Fri, 5 Nov 2021 16:30:32 +0800 Subject: [PATCH 45/94] fix codestyle Signed-off-by: xionglei6 --- test/unittest/package/pkg_package_unittest.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unittest/package/pkg_package_unittest.cpp b/test/unittest/package/pkg_package_unittest.cpp index 919e0fe6..bdd92603 100755 --- a/test/unittest/package/pkg_package_unittest.cpp +++ b/test/unittest/package/pkg_package_unittest.cpp @@ -122,7 +122,6 @@ public: EXPECT_NE(pkgManager_, nullptr); PkgManager::StreamPtr stream = nullptr; std::string packagePath = TEST_PATH_TO; - uint32_t zipNodeId = 100; packagePath += testPackageName; pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); EXPECT_NE(stream, nullptr); -- Gitee From 529ca50e97a65594224a8dde242074e5296b97cf Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Fri, 5 Nov 2021 19:22:58 +0800 Subject: [PATCH 46/94] updater: fix bugs Signed-off-by: xionglei6 --- interfaces/kits/updaterkits/updaterkits.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/updaterkits/updaterkits.cpp b/interfaces/kits/updaterkits/updaterkits.cpp index 60ac4c5e..bfc2a6a4 100755 --- a/interfaces/kits/updaterkits/updaterkits.cpp +++ b/interfaces/kits/updaterkits/updaterkits.cpp @@ -39,7 +39,7 @@ static bool WriteToMiscAndRebootToUpdater(const std::string &miscFile, int32_t propertyMaxSize = 92; char updateCmd[propertyMaxSize]; void(snprintf_s(updateCmd, propertyMaxSize, propertyMaxSize - 1, "reboot,updater:%s", updateMsg.update)); - bool bRet = OHOS::system::SetParameter("sys.powerctrl", updateCmd); + bool bRet = OHOS::system::SetParameter("ohos.startup.powerctrl", updateCmd); if (!bRet) { std::cout << "WriteToMiscAndRebootToUpdater SetParameter failed, errno: " << errno << std::endl; return false; -- Gitee From ecd1e2b595e0999f58fbe1afb26dc29c513a59e4 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Fri, 5 Nov 2021 19:48:30 +0800 Subject: [PATCH 47/94] updater: fix test data Signed-off-by: xionglei6 --- test/unittest/test_data/updater/updater.zip | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unittest/test_data/updater/updater.zip b/test/unittest/test_data/updater/updater.zip index eeae4e4b..0ecd1ceb 100755 --- a/test/unittest/test_data/updater/updater.zip +++ b/test/unittest/test_data/updater/updater.zip @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ab06b6f2a1dbb8563f7da65e79a70a6550620428f7704cca6159e56481d4d1c1 -size 1785615 +oid sha256:14357f75170e22c61470c2cd0fe73ee4f4b1a3396ac5d386433e76c0e54d0cd9 +size 13387850 -- Gitee From 56455d1fd076b5494bb50651d3377ebbb7123f29 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Fri, 5 Nov 2021 20:10:58 +0800 Subject: [PATCH 48/94] updater: fix bugs Signed-off-by: xionglei6 --- services/flashd/host/host_updater.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/services/flashd/host/host_updater.cpp b/services/flashd/host/host_updater.cpp index 641af6ac..f2c610ac 100755 --- a/services/flashd/host/host_updater.cpp +++ b/services/flashd/host/host_updater.cpp @@ -302,7 +302,6 @@ bool HostUpdater::CheckMatchUpdate(const std::string &input, bool HostUpdater::ConfirmCommand(const string &commandIn) { - bool needConfirm = false; std::string tip = ""; WRITE_LOG(LOG_DEBUG, "ConfirmCommand \"%s\" \n", commandIn.c_str()); @@ -348,4 +347,4 @@ bool HostUpdater::ConfirmCommand(const string &commandIn) } while (1); return true; } -} // namespace Hdc \ No newline at end of file +} // namespace Hdc -- Gitee From 88cb15b59ffe716bf6d8feaf384ae475fdb215bd Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Mon, 8 Nov 2021 11:03:29 +0800 Subject: [PATCH 49/94] updater: fix flashed Signed-off-by: xionglei6 --- services/flashd/flash_service.cpp | 17 +++++++++++++---- services/flashd/host/host_updater.cpp | 2 +- services/include/flashd/flashd.h | 12 ++++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/services/flashd/flash_service.cpp b/services/flashd/flash_service.cpp index 4b49ef7e..a1004b6f 100755 --- a/services/flashd/flash_service.cpp +++ b/services/flashd/flash_service.cpp @@ -214,7 +214,7 @@ PartitionPtr FlashService::GetPartition(const std::string &partition) const { const std::string partName = GetPartNameByAlias(partition); for (auto part : partitions_) { - if (partName.compare(part->GetPartitionName()) == 0) { + if (strcmp(partName.c_str(), part->GetPartitionName().c_str()) == 0) { return part; } } @@ -431,7 +431,7 @@ const std::string FlashService::GetPartNameByAlias(const std::string &alias) }; for (auto iter = partNameMap.begin(); iter != partNameMap.end(); iter++) { for (auto iter2 = iter->second.begin(); iter2 != iter->second.end(); iter2++) { - if (*iter2 == alias) { + if (strcmp(alias.c_str(), (*iter2).c_str()) == 0) { return iter->first; } } @@ -461,7 +461,7 @@ static std::string GetValueFromParam(const std::vector ¶ms, { std::string ret = defValue; for (size_t i = 0; i < params.size(); i++) { - if (paramType.compare(params[i]) == 0) { + if (strcmp(paramType.c_str(), params[i].c_str()) == 0) { if (i < (params.size() - 1)) { ret = params[i + 1]; } else { @@ -476,7 +476,7 @@ static bool FilterParam(const std::string ¶m, const std::vector { auto iter = filter.begin(); while (iter != filter.end()) { - if (param.compare(*iter) == 0) { + if (strcmp(param.c_str(), (*iter).c_str()) == 0) { return true; } iter++; @@ -632,4 +632,13 @@ int DoUpdaterFinish(FlashHandle handle, uint8_t type, const std::string &partiti g_flashdRunning = false; return 0; } + +int SetParameter(const char *key, const char *value) +{ + std::string sKey = key; + std::string sValue = value; + std::string sBuf = "param set " + sKey + " " + value; + system(sBuf.c_str()); + return 0; +} } // namespace flashd diff --git a/services/flashd/host/host_updater.cpp b/services/flashd/host/host_updater.cpp index f2c610ac..6a11cb3f 100755 --- a/services/flashd/host/host_updater.cpp +++ b/services/flashd/host/host_updater.cpp @@ -277,7 +277,7 @@ bool HostUpdater::CheckMatchUpdate(const std::string &input, bJumpDo = true; return true; } - int cmdLen = updateCmd.size(); + size_t cmdLen = updateCmd.size(); if (!strncmp(input.c_str(), updateCmd.c_str(), updateCmd.size())) { cmdFlag = CMD_UPDATER_UPDATE_INIT; cmdLen = updateCmd.size(); diff --git a/services/include/flashd/flashd.h b/services/include/flashd/flashd.h index 8d46b976..13af8557 100755 --- a/services/include/flashd/flashd.h +++ b/services/include/flashd/flashd.h @@ -67,5 +67,17 @@ int CreateFlashInstance(FlashHandle *handle, std::string &errorMsg, ProgressFunc int DoUpdaterPrepare(FlashHandle handle, uint8_t type, const std::string &cmdParam, std::string &filePath); int DoUpdaterFlash(FlashHandle handle, uint8_t type, const std::string &cmdParam, const std::string &filePath); int DoUpdaterFinish(FlashHandle handle, uint8_t type, const std::string &partition); + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif +int SetParameter(const char *key, const char *value); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif } // namespace flashd #endif /* UPDATER_FLASHING_H */ -- Gitee From d24f51e87a7b9e3179f10de2d6a13f4c53d0d3ec Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Wed, 10 Nov 2021 19:33:03 +0800 Subject: [PATCH 50/94] flashd: fix cmd for updater_reboot Signed-off-by: xionglei6 --- services/diffpatch/diff/blocks_diff.cpp | 4 +- services/diffpatch/diff/blocks_diff.h | 4 +- services/flashd/flash_service.cpp | 3 +- services/flashd/host/host_updater.cpp | 60 +++++--- services/flashd/host/host_updater.h | 13 +- services/main.cpp | 2 + services/updater_binary/main.cpp | 3 +- test/unittest/BUILD.gn | 4 +- .../applypatch_test/imagepatch_unittest.h | 4 +- .../flashd_test/flash_host_unittest.cpp | 130 +++++++++++++++--- .../flashd_test/flash_service_unittest.cpp | 6 +- .../unittest/package/pkg_package_unittest.cpp | 8 +- test/unittest/test_data/updater/updater.zip | 4 +- .../updater_binary_unittest.cpp | 18 ++- utils/updater_reboot.cpp | 8 +- utils/utils.cpp | 2 +- 16 files changed, 187 insertions(+), 86 deletions(-) diff --git a/services/diffpatch/diff/blocks_diff.cpp b/services/diffpatch/diff/blocks_diff.cpp index 2a68f28c..d579dbd9 100644 --- a/services/diffpatch/diff/blocks_diff.cpp +++ b/services/diffpatch/diff/blocks_diff.cpp @@ -237,7 +237,7 @@ void BlocksDiff::ComputeLength(const BlockBuffer &newInfo, int64_t i = 0; int64_t s = 0; int64_t tmp = 0; - for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length));) { + for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length)); ) { if (oldInfo.buffer[lastPos_ + i] == newInfo.buffer[lastScan_ + i]) { s++; } @@ -413,7 +413,7 @@ void SuffixArray::Init(const BlockBuffer &oldInfo) DataType len = 0; for (h = 1; suffixArray_[0] != -(static_cast(oldInfo.length) + 1); h += h) { len = 0; - for (i = 0; i < (static_cast(oldInfo.length) + 1);) { + for (i = 0; i < (static_cast(oldInfo.length) + 1); ) { if (suffixArray_[i] < 0) { len -= suffixArray_[i]; i -= suffixArray_[i]; diff --git a/services/diffpatch/diff/blocks_diff.h b/services/diffpatch/diff/blocks_diff.h index dc682eac..5dd76fa9 100644 --- a/services/diffpatch/diff/blocks_diff.h +++ b/services/diffpatch/diff/blocks_diff.h @@ -89,7 +89,7 @@ public: private: std::unique_ptr CreateBZip2Adapter(size_t patchOffset) override; int32_t WritePatchHeader(int64_t controlSize, - int64_t diffDataSize, int64_t newSize, size_t &patchOffset) override; + int64_t diffDataSize, int64_t newSize, size_t &headerLen) override; std::fstream &stream_; size_t offset_ { 0 }; }; @@ -102,7 +102,7 @@ public: private: std::unique_ptr CreateBZip2Adapter(size_t patchOffset) override; int32_t WritePatchHeader(int64_t controlSize, - int64_t diffDataSize, int64_t newSize, size_t &patchOffset) override; + int64_t diffDataSize, int64_t newSize, size_t &headerLen) override; std::vector &patchData_; size_t offset_ { 0 }; }; diff --git a/services/flashd/flash_service.cpp b/services/flashd/flash_service.cpp index a1004b6f..c5050ba0 100755 --- a/services/flashd/flash_service.cpp +++ b/services/flashd/flash_service.cpp @@ -557,7 +557,8 @@ int DoUpdaterPrepare(FlashHandle handle, uint8_t type, const std::string &cmdPar return FLASHING_INVALID_SPACE, "Failed to mount data paratition for %s", filePath.c_str()); ret = flash->DoResizeParatiton(root, MIN_BLOCKS_FOR_UPDATE); - FLASHING_CHECK(ret == 0, g_flashdRunning = false; return ret, "Failed to resize partition"); + FLASHING_CHECK(ret == 0, g_flashdRunning = false; + return ret, "Failed to resize partition"); if (access(FLASHD_FILE_PATH.c_str(), F_OK) == -1) { mkdir(FLASHD_FILE_PATH.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); } diff --git a/services/flashd/host/host_updater.cpp b/services/flashd/host/host_updater.cpp index 6a11cb3f..00beb0f8 100755 --- a/services/flashd/host/host_updater.cpp +++ b/services/flashd/host/host_updater.cpp @@ -48,7 +48,7 @@ bool HostUpdater::BeginTransfer(CtxFile &context, { int argc = 0; char **argv = Base::SplitCommandToArgs(payload, &argc); - FLASHHOST_CHECK(!(argv == nullptr || argc < minParam || fileIndex >= argc), delete[]((char *)argv); + HOSTUPDATER_CHECK(!(argv == nullptr || argc < minParam || fileIndex >= argc), delete[]((char *)argv); return false, "Invalid param for cmd \"%s\"", function.c_str()); int maxParam = minParam; @@ -56,7 +56,7 @@ bool HostUpdater::BeginTransfer(CtxFile &context, if (force) { maxParam += 1; } - FLASHHOST_CHECK(argc == maxParam, delete[]((char *)argv); + HOSTUPDATER_CHECK(argc == maxParam, delete[]((char *)argv); return false, "Invalid param for cmd \"%s\" %d", function.c_str(), maxParam); context.transferConfig.functionName = function; @@ -71,11 +71,11 @@ bool HostUpdater::BeginTransfer(CtxFile &context, context.transferConfig.compressType = COMPRESS_NONE; } else if (MatchPackageExtendName(context.localPath, ".bin")) { const char *part = strstr(payload, "fastboot"); - FLASHHOST_CHECK(part != nullptr, delete[]((char *)argv); + HOSTUPDATER_CHECK(part != nullptr, delete[]((char *)argv); return false, "Invalid image %s for cmd \"%s\"", context.localPath.c_str(), function.c_str()); context.transferConfig.compressType = COMPRESS_NONE; } else { - FLASHHOST_CHECK((MatchPackageExtendName(context.localPath, ".zip") || + HOSTUPDATER_CHECK((MatchPackageExtendName(context.localPath, ".zip") || MatchPackageExtendName(context.localPath, ".lz4") || MatchPackageExtendName(context.localPath, ".gz2")), delete[]((char *)argv); return false, @@ -86,7 +86,7 @@ bool HostUpdater::BeginTransfer(CtxFile &context, context.transferConfig.functionName.c_str(), context.localPath.c_str(), payload); // check path bool ret = Base::CheckDirectoryOrPath(context.localPath.c_str(), true, true); - FLASHHOST_CHECK(ret, delete[]((char *)argv); + HOSTUPDATER_CHECK(ret, delete[]((char *)argv); return false, "Invaid path \"%s\" for cmd \"%s\"", context.localPath.c_str(), function.c_str()); context.taskQueue.push_back(context.localPath); @@ -134,9 +134,9 @@ bool HostUpdater::CheckCmd(const std::string &function, const char *payload, int { int argc = 0; char **argv = Base::SplitCommandToArgs(payload, &argc); - FLASHHOST_CHECK(argv != nullptr, return false, "Can not parser cmd \"%s\"", function.c_str()); + HOSTUPDATER_CHECK(argv != nullptr, return false, "Can not parser cmd \"%s\"", function.c_str()); delete[]((char *)argv); - FLASHHOST_CHECK(argc >= param, return false, "Invalid param for cmd \"%s\" %d", function.c_str(), argc); + HOSTUPDATER_CHECK(argc >= param, return false, "Invalid param for cmd \"%s\" %d", function.c_str(), argc); WRITE_LOG(LOG_DEBUG, "CheckCmd command: %s ", payload); int maxParam = param; @@ -147,7 +147,7 @@ bool HostUpdater::CheckCmd(const std::string &function, const char *payload, int maxParam += 1; maxParam += 1; } - FLASHHOST_CHECK(argc == maxParam, return false, + HOSTUPDATER_CHECK(argc == maxParam, return false, "Invalid param for cmd \"%s\" %d %d", function.c_str(), argc, maxParam); return true; } @@ -165,7 +165,7 @@ bool HostUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, cons switch (command) { case CMD_UPDATER_BEGIN: { std::string s(" Processing: 0%%"); - bSendProgress = true; + sendProgress = true; SendRawData(reinterpret_cast(s.data()), s.size()); break; } @@ -208,7 +208,7 @@ bool HostUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, cons void HostUpdater::ProcessProgress(uint32_t percentage) { - if (!bSendProgress) { + if (!sendProgress) { return; } std::string backStr = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; @@ -219,24 +219,24 @@ void HostUpdater::ProcessProgress(uint32_t percentage) if (percentage == PERCENT_CLEAR) { // clear SendRawData(reinterpret_cast(backStr.data()), backStr.size()); SendRawData(reinterpret_cast(breakStr.data()), breakStr.size()); - bSendProgress = false; + sendProgress = false; return; } int len = sprintf_s(buffer.data(), buffer.size() - 1, "%s Processing: %3d%%", backStr.c_str(), percentage); - FLASHHOST_CHECK(len > 0, return, "Failed to format progress info "); + HOSTUPDATER_CHECK(len > 0, return, "Failed to format progress info "); SendRawData(reinterpret_cast(buffer.data()), len); if (percentage == PERCENT_FINISH) { SendRawData(reinterpret_cast(breakStr.data()), breakStr.size()); - bSendProgress = false; + sendProgress = false; } } bool HostUpdater::CheckUpdateContinue(const uint16_t command, const uint8_t *payload, int payloadSize) { - FLASHHOST_CHECK(static_cast(payloadSize) >= sizeof(uint16_t), + HOSTUPDATER_CHECK(static_cast(payloadSize) >= sizeof(uint16_t), return false, "Failed to check payload size %d ", payloadSize); MessageLevel level = (MessageLevel)payload[1]; - if ((level == MSG_OK) && bSendProgress) { + if ((level == MSG_OK) && sendProgress) { ProcessProgress(PERCENT_FINISH); } std::string info((char*)(payload + sizeof(uint16_t)), payloadSize - sizeof(uint16_t)); @@ -256,8 +256,7 @@ bool HostUpdater::CheckUpdateContinue(const uint16_t command, const uint8_t *pay std::string HostUpdater::GetFlashdHelp() { - string help; - help = "\n---------------------------------flash commands:-------------------------------------\n" + string help = "\n---------------------------------flash commands:-------------------------------------\n" "flash commands:\n" " target boot [-flashd] - Reboot the device or boot into flashd\n" " update packagename - Update system by package\n" @@ -300,13 +299,22 @@ bool HostUpdater::CheckMatchUpdate(const std::string &input, return true; } -bool HostUpdater::ConfirmCommand(const string &commandIn) +#ifdef UPDATER_UT +static std::string g_input = "yes"; +void HostUpdater::SetInput(const std::string &input) +{ + g_input = input; +} +#endif +bool HostUpdater::ConfirmCommand(const string &commandIn, bool &closeInput) { std::string tip = ""; WRITE_LOG(LOG_DEBUG, "ConfirmCommand \"%s\" \n", commandIn.c_str()); - - if (!strncmp(commandIn.c_str(), flashCmd.c_str(), flashCmd.size())) { + if (!strncmp(commandIn.c_str(), updateCmd.c_str(), updateCmd.size())) { + closeInput = true; + } else if (!strncmp(commandIn.c_str(), flashCmd.c_str(), flashCmd.size())) { tip = "Confirm flash partition"; + closeInput = true; } else if (!strncmp(commandIn.c_str(), eraseCmd.c_str(), eraseCmd.size())) { tip = "Confirm erase partition"; } else if (!strncmp(commandIn.c_str(), formatCmd.c_str(), formatCmd.size())) { @@ -320,13 +328,19 @@ bool HostUpdater::ConfirmCommand(const string &commandIn) return true; } const size_t minLen = strlen("yes"); + int retryCount = 0; do { printf(" %s ? (Yes/No) ", tip.c_str()); fflush(stdin); std::string info = {}; size_t i = 0; while (1) { +#ifndef UPDATER_UT char c = getchar(); +#else + char c = '\n'; + info = g_input; +#endif if (c == '\r' || c == '\n') { break; } @@ -344,7 +358,11 @@ bool HostUpdater::ConfirmCommand(const string &commandIn) if (info == "y" || info == "yes") { return true; } - } while (1); + retryCount++; + } while (retryCount < 3); // 3 retry max count + if (retryCount >= 3) { // 3 retry max count + return false; + } return true; } } // namespace Hdc diff --git a/services/flashd/host/host_updater.h b/services/flashd/host/host_updater.h index 9329419a..2e627782 100755 --- a/services/flashd/host/host_updater.h +++ b/services/flashd/host/host_updater.h @@ -18,15 +18,11 @@ #include "transfer.h" namespace Hdc { -#define FLASHHOST_CHECK(retCode, exper, ...) \ +#define HOSTUPDATER_CHECK(retCode, exper, ...) \ if (!(retCode)) { \ LogMsg(MSG_FAIL, __VA_ARGS__); \ exper; \ } -#define FLASHHOST_ONLY_CHECK(retCode, exper) \ - if (!(retCode)) { \ - exper; \ - } class HostUpdater : public HdcTransferBase { public: @@ -36,16 +32,16 @@ public: static std::string GetFlashdHelp(); static bool CheckMatchUpdate(const std::string &input, std::string &stringError, uint16_t &cmdFlag, bool &bJumpDo); - static bool ConfirmCommand(const string &commandIn); + static bool ConfirmCommand(const string &commandIn, bool &closeInput); #ifdef UPDATER_UT void OpenFile() { CheckMaster(&ctxNow); } + static void SetInput(const std::string &input); #endif private: void CheckMaster(CtxFile *context) override; - bool BeginTransfer(CtxFile &context, const std::string &function, const char *payload, int minParam, int fileIndex); bool CheckUpdateContinue(const uint16_t command, const uint8_t *payload, int payloadSize); @@ -71,8 +67,7 @@ private: #endif private: bool CheckCmd(const std::string &function, const char *payload, int param); - - bool bSendProgress = false; + bool sendProgress = false; }; } #endif \ No newline at end of file diff --git a/services/main.cpp b/services/main.cpp index 6f5d5fe9..d6a5e6da 100644 --- a/services/main.cpp +++ b/services/main.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "fs_manager/mount.h" +#include "fs_manager/fs_manager_log.h" #include "flashd/flashd.h" #include "log/log.h" #include "misc_info/misc_info.h" @@ -32,6 +33,7 @@ int main(int argc, char **argv) InitUpdaterLogger((mode == BOOT_FLASHD) ? "FLASHD" : "UPDATER", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); SetLogLevel(INFO); + FsManagerLogInit(LOG_TO_FILE, TMP_LOG.c_str()); LoadFstab(); STAGE(UPDATE_STAGE_OUT) << "Start " << ((mode == BOOT_FLASHD) ? "flashd" : "updater"); if (mode == BOOT_FLASHD) { diff --git a/services/updater_binary/main.cpp b/services/updater_binary/main.cpp index 775c17c1..62542a9b 100644 --- a/services/updater_binary/main.cpp +++ b/services/updater_binary/main.cpp @@ -18,6 +18,7 @@ #include #include #include "fs_manager/mount.h" +#include "fs_manager/fs_manager_log.h" #include "log.h" #include "updater/updater_const.h" #include "update_processor.h" @@ -32,7 +33,7 @@ int main(int argc, char **argv) LOG(ERROR) << "Invalid arguments."; return EXIT_INVALID_ARGS; } - + FsManagerLogInit(LOG_TO_FILE, TMP_LOG.c_str()); bool retry = false; int pipeFd = static_cast(std::strtol(argv[1], nullptr, DECIMAL)); if (argc >= BINARY_MAX_ARGS && strcmp(argv[BINARY_SECOND_ARG], "retry") == 0) { diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 5a7a54c8..9cd5a399 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -44,8 +44,8 @@ ohos_unittest("updater_unittest") { "applypatch_test/transfer_manager_unittest.cpp", "diffpatch/bzip2_unittest.cpp", "diffpatch/diffpatch_unittest.cpp", - "flashd_test/flash_host_unittest.cpp", "flashd_test/flash_service_unittest.cpp", + "flashd_test/flash_host_unittest.cpp", "fs_manager/do_partition_unittest.cpp", "log_test/log_unittest.cpp", "misc_info_test/misc_info_unittest.cpp", @@ -96,8 +96,8 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/flashd/blockdevice.cpp", "//base/update/updater/services/flashd/daemon/daemon_updater.cpp", "//base/update/updater/services/flashd/daemon/flashd_main.cpp", - "//base/update/updater/services/flashd/flash_service.cpp", "//base/update/updater/services/flashd/host/host_updater.cpp", + "//base/update/updater/services/flashd/flash_service.cpp", "//base/update/updater/services/flashd/partition.cpp", "//base/update/updater/services/fs_manager/cmp_partition.cpp", "//base/update/updater/services/fs_manager/do_partition.cpp", diff --git a/test/unittest/applypatch_test/imagepatch_unittest.h b/test/unittest/applypatch_test/imagepatch_unittest.h index e4cdc358..6da5f553 100755 --- a/test/unittest/applypatch_test/imagepatch_unittest.h +++ b/test/unittest/applypatch_test/imagepatch_unittest.h @@ -77,7 +77,9 @@ public: int fd = open(target.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY, mode); EXPECT_GE(fd, 0); BlockSet targetBlk; - targetBlk.ParserAndInsert({"2", "0", "1"}); + targetBlk.ParserAndInsert({ + "2", "0", "1" + }); std::unique_ptr writer = std::make_unique(fd, targetBlk); std::vector empty; int32_t ret = updatepatch::UpdatePatch::ApplyImagePatch(param, empty, diff --git a/test/unittest/flashd_test/flash_host_unittest.cpp b/test/unittest/flashd_test/flash_host_unittest.cpp index fe97130e..0b9c580f 100755 --- a/test/unittest/flashd_test/flash_host_unittest.cpp +++ b/test/unittest/flashd_test/flash_host_unittest.cpp @@ -46,9 +46,6 @@ public: public: int TestFlashHost(uint16_t command, const std::string &cmd) { - uv_loop_t loopMain; - uv_loop_init(&loopMain); - HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); if (task == nullptr) { @@ -57,21 +54,21 @@ public: hTaskInfo = task.get(); hTaskInfo->channelId = 1; hTaskInfo->sessionId = 0; - hTaskInfo->runLoop = &loopMain; + hTaskInfo->runLoop = uv_default_loop(); hTaskInfo->serverOrDaemon = 0; + hTaskInfo->ownerSessionClass = nullptr; std::shared_ptr flashHost = std::make_shared(hTaskInfo); if (flashHost == nullptr) { return -1; } flashHost->CommandDispatch(command, const_cast(reinterpret_cast(cmd.data())), cmd.size()); + return 0; } int TestFlashProgress(uint16_t command, const std::string &cmd, uint32_t progress) { - uv_loop_t loopMain; - uv_loop_init(&loopMain); HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); @@ -81,8 +78,9 @@ public: hTaskInfo = task.get(); hTaskInfo->channelId = 1; hTaskInfo->sessionId = 0; - hTaskInfo->runLoop = &loopMain; + hTaskInfo->runLoop = uv_default_loop(); hTaskInfo->serverOrDaemon = 0; + hTaskInfo->ownerSessionClass = nullptr; std::shared_ptr flashHost = std::make_shared(hTaskInfo); if (flashHost == nullptr) { return -1; @@ -110,7 +108,7 @@ public: flashHost->CommandDispatch(CMD_UPDATER_PROGRESS, const_cast(reinterpret_cast(cmdInfo.data())), cmdInfo.size()); - percentage = (uint32_t)progress; + percentage = static_cast(progress); cmdInfo.resize(sizeof(percentage)); (void)memcpy_s(cmdInfo.data(), cmdInfo.size(), &percentage, sizeof(percentage)); flashHost->CommandDispatch(CMD_UPDATER_PROGRESS, @@ -120,30 +118,34 @@ public: } }; -HWTEST_F(FLashHostUnitTest, TestFlashHost, TestSize.Level1) +HWTEST_F(FLashHostUnitTest, TestFlashHostErase, TestSize.Level1) { FLashHostUnitTest test; Base::SetLogLevel(LOG_LAST); // debug log print - std::string cmdParam = TEST_UPDATER_PACKAGE_PATH; - EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_UPDATE_INIT, cmdParam)); + std::string cmdParam = "erase -f "; + cmdParam += TEST_PARTITION_NAME; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_ERASE, cmdParam)); +} - cmdParam = " -f "; - cmdParam += TEST_PARTITION_NAME + " "; - cmdParam += TEST_FLASH_IMAGE_NAME; - EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FLASH_INIT, cmdParam)); +HWTEST_F(FLashHostUnitTest, TestFlashHostFormat, TestSize.Level1) +{ + FLashHostUnitTest test; + Base::SetLogLevel(LOG_LAST); // debug log print - cmdParam = "erase -f "; + std::string cmdParam = "format -f "; cmdParam += TEST_PARTITION_NAME; - EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_ERASE, cmdParam)); + cmdParam += " -t ext4"; + EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FORMAT, cmdParam)); - cmdParam = "format -f "; + + cmdParam = "format "; cmdParam += TEST_PARTITION_NAME; cmdParam += " -t ext4"; EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FORMAT, cmdParam)); } -HWTEST_F(FLashHostUnitTest, TestFlashProgress, TestSize.Level1) +HWTEST_F(FLashHostUnitTest, TestFlashHostUpdater, TestSize.Level1) { FLashHostUnitTest test; Base::SetLogLevel(LOG_LAST); // debug log print @@ -157,17 +159,103 @@ HWTEST_F(FLashHostUnitTest, TestFlashProgress, TestSize.Level1) EXPECT_EQ(0, test.TestFlashProgress(CMD_UPDATER_FLASH_INIT, cmdParam, -1)); } -HWTEST_F(FLashHostUnitTest, TestFlashProgressFinish, TestSize.Level1) +HWTEST_F(FLashHostUnitTest, TestFlashHostFlash, TestSize.Level1) { FLashHostUnitTest test; Base::SetLogLevel(LOG_LAST); // debug log print std::string cmdParam = TEST_UPDATER_PACKAGE_PATH; EXPECT_EQ(0, test.TestFlashProgress(CMD_UPDATER_UPDATE_INIT, cmdParam, 100)); - cmdParam = " -f "; cmdParam += TEST_PARTITION_NAME + " "; cmdParam += TEST_FLASH_IMAGE_NAME; EXPECT_EQ(0, test.TestFlashProgress(CMD_UPDATER_FLASH_INIT, cmdParam, 100)); } + +HWTEST_F(FLashHostUnitTest, TestFlashHostHelp, TestSize.Level1) +{ + std::string help = HostUpdater::GetFlashdHelp(); + printf("%s", help.c_str()); +} + +HWTEST_F(FLashHostUnitTest, TestFlashHostMatch, TestSize.Level1) +{ + std::string stringError; + uint16_t cmdFlag = 0; + bool bJumpDo = false; + bool ret = HostUpdater::CheckMatchUpdate("update updater.zip", stringError, cmdFlag, bJumpDo); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(cmdFlag, CMD_UPDATER_UPDATE_INIT); + EXPECT_EQ(bJumpDo == false, 1); + + ret = HostUpdater::CheckMatchUpdate("flash updater.zip", stringError, cmdFlag, bJumpDo); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(cmdFlag, CMD_UPDATER_FLASH_INIT); + EXPECT_EQ(bJumpDo == false, 1); + + ret = HostUpdater::CheckMatchUpdate("erase -f updater", stringError, cmdFlag, bJumpDo); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(cmdFlag, CMD_UPDATER_ERASE); + EXPECT_EQ(bJumpDo == false, 1); + + ret = HostUpdater::CheckMatchUpdate("format -f updater ", stringError, cmdFlag, bJumpDo); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(cmdFlag, CMD_UPDATER_FORMAT); + EXPECT_EQ(bJumpDo == false, 1); + + ret = HostUpdater::CheckMatchUpdate("flash", stringError, cmdFlag, bJumpDo); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(cmdFlag, CMD_KERNEL_HELP); + EXPECT_EQ(bJumpDo == true, 1); + + bJumpDo = false; + ret = HostUpdater::CheckMatchUpdate("install aaa.hap", stringError, cmdFlag, bJumpDo); + EXPECT_EQ(ret == false, 1); + EXPECT_EQ(bJumpDo == false, 1); +} + +HWTEST_F(FLashHostUnitTest, TestFlashHostConfirm, TestSize.Level1) +{ + bool closeInput = false; + bool ret = HostUpdater::ConfirmCommand("update updater.zip", closeInput); + EXPECT_EQ(ret == true, 1); + + HostUpdater::SetInput("yes"); + closeInput = false; + ret = HostUpdater::ConfirmCommand("flash updater.zip", closeInput); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(closeInput == true, 1); + + closeInput = false; + ret = HostUpdater::ConfirmCommand("erase updater", closeInput); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(closeInput == false, 1); + + closeInput = false; + ret = HostUpdater::ConfirmCommand("format updater", closeInput); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(closeInput == false, 1); + + closeInput = false; + ret = HostUpdater::ConfirmCommand("format -f updater", closeInput); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(closeInput == false, 1); + + closeInput = false; + ret = HostUpdater::ConfirmCommand("erase -f updater", closeInput); + EXPECT_EQ(ret == true, 1); + EXPECT_EQ(closeInput == false, 1); + + HostUpdater::SetInput("no"); + closeInput = false; + ret = HostUpdater::ConfirmCommand("format updater", closeInput); + EXPECT_EQ(ret == false, 1); + EXPECT_EQ(closeInput == false, 1); + + HostUpdater::SetInput("eeeeeeeee"); + closeInput = false; + ret = HostUpdater::ConfirmCommand("format updater", closeInput); + EXPECT_EQ(ret == false, 1); + EXPECT_EQ(closeInput == false, 1); +} } // namespace \ No newline at end of file diff --git a/test/unittest/flashd_test/flash_service_unittest.cpp b/test/unittest/flashd_test/flash_service_unittest.cpp index 3a33c1cf..3272f947 100755 --- a/test/unittest/flashd_test/flash_service_unittest.cpp +++ b/test/unittest/flashd_test/flash_service_unittest.cpp @@ -192,7 +192,7 @@ public: // begin hdcDamon->CommandDispatch(CMD_UPDATER_BEGIN, NULL, 0); - for (int i = 0; i < 100; i++) { // 10 send time + for (int i = 0; i < 10; i++) { // 10 send time HdcTransferBase::TransferPayload payloadHead {}; payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; payloadHead.uncompressSize = transferConfig.fileSize / 10; // 10 time @@ -298,10 +298,6 @@ public: std::string bufData = SerialStruct::SerializeToString(payloadHead); hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); } - payloadHead.compressType = HdcTransferBase::COMPRESS_NONE; - payloadHead.uncompressSize = transferConfig.fileSize / 10; // 10 time - payloadHead.compressSize = transferConfig.fileSize / 10; // 10 time - payloadHead.index = 0; std::string bufData = SerialStruct::SerializeToString(payloadHead); hdcDamon->CommandDispatch(CMD_UPDATER_DATA, reinterpret_cast(bufData.data()), bufData.size()); // end diff --git a/test/unittest/package/pkg_package_unittest.cpp b/test/unittest/package/pkg_package_unittest.cpp index bdd92603..2880e5cd 100755 --- a/test/unittest/package/pkg_package_unittest.cpp +++ b/test/unittest/package/pkg_package_unittest.cpp @@ -38,8 +38,6 @@ namespace { constexpr uint32_t MAX_FILE_NAME = 256; constexpr uint32_t CENTRAL_SIGNATURE = 0x02014b50; constexpr uint32_t END_CENTRAL_SIGNATURE = 0x06054b50; -constexpr uint32_t ZIP_NODE_ID = 100; -constexpr size_t GIANT_NUMBER = 100000; class TestFile : public PkgFile { public: @@ -122,13 +120,14 @@ public: EXPECT_NE(pkgManager_, nullptr); PkgManager::StreamPtr stream = nullptr; std::string packagePath = TEST_PATH_TO; + uint32_t zipNodeId = 100; packagePath += testPackageName; pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); EXPECT_NE(stream, nullptr); std::unique_ptr file = std::make_unique(pkgManager_, PkgStreamImpl::ConvertPkgStream(stream)); EXPECT_NE(file, nullptr); - std::unique_ptr entry = std::make_unique(file.get(), ZIP_NODE_ID); + std::unique_ptr entry = std::make_unique(file.get(), zipNodeId); EXPECT_NE(entry, nullptr); string name = "TestBigZip"; @@ -162,7 +161,8 @@ public: EXPECT_EQ(ret, 0); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length(), 1); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetHalfWord, offset4Words); - size_t size = UINT_MAX + GIANT_NUMBER; + size_t giantNumber = 100000; + size_t size = UINT_MAX + giantNumber; WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetWord, size); WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offset3Words, size); size_t decodeLen = 0; diff --git a/test/unittest/test_data/updater/updater.zip b/test/unittest/test_data/updater/updater.zip index 0ecd1ceb..25795ea9 100755 --- a/test/unittest/test_data/updater/updater.zip +++ b/test/unittest/test_data/updater/updater.zip @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14357f75170e22c61470c2cd0fe73ee4f4b1a3396ac5d386433e76c0e54d0cd9 -size 13387850 +oid sha256:d42c282d8f74c3bde0243a39b94150b30f7273bed463a3eaae6a26454bb9eaec +size 1785455 diff --git a/test/unittest/updater_binary/updater_binary_unittest.cpp b/test/unittest/updater_binary/updater_binary_unittest.cpp index 65975e54..d6a48a4d 100755 --- a/test/unittest/updater_binary/updater_binary_unittest.cpp +++ b/test/unittest/updater_binary/updater_binary_unittest.cpp @@ -112,25 +112,26 @@ protected: { int32_t ret; int32_t updateFileVersion = 1000; - int fileNameIndex = 3; - uint8_t componentType = 22; + PKG_LOGI("\n\n ************* CreatePackageBin %s \r\n", testPackageName.c_str()); UpgradePkgInfoExt pkgInfo; - ComponentInfoExt *comp = (ComponentInfoExt*)malloc( - sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); - if (comp == nullptr) { - return -1; - } // C API, Cannot use c++ string class. pkgInfo.softwareVersion = strdup("100.100.100.100"); pkgInfo.date = strdup("2021-02-02"); pkgInfo.time = strdup("21:23:49"); pkgInfo.productUpdateId = strdup("555.555.100.555"); + int fileNameIndex = 3; + uint8_t componentType = 22; pkgInfo.entryCount = testFileNames_.size() + fileNameIndex; pkgInfo.updateFileVersion = updateFileVersion; pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE; + ComponentInfoExt *comp = (ComponentInfoExt*)malloc( + sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); + if (comp == nullptr) { + return -1; + } for (size_t i = 0; i < testFileNames_.size(); i++) { BuildCompnentInfo(comp[i], testFileNames_[i], testFileNames_[i], componentType); } @@ -143,9 +144,6 @@ protected: std::string packagePath = TEST_PATH_TO; packagePath += testPackageName; ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(), GetTestPrivateKeyName().c_str()); - if (ret == 0) { - PKG_LOGI("CreatePackage success offset"); - } for (size_t i = 0; i < index; i++) { free(comp[i].componentAddr); free(comp[i].filePath); diff --git a/utils/updater_reboot.cpp b/utils/updater_reboot.cpp index 7c57ff61..42e189f8 100644 --- a/utils/updater_reboot.cpp +++ b/utils/updater_reboot.cpp @@ -32,12 +32,12 @@ int main(int argc, char **argv) std::string updaterStr = "updater"; if (!memcmp(argv[1], updaterStr.c_str(), updaterStr.length())) { updater::utils::DoReboot(argv[1]); - } else if (strcmp(argv[1], "flash") == 0) { + } else if (strcmp(argv[1], "flashd") == 0) { updater::utils::DoReboot(argv[1]); - } else if (strncmp(argv[1], "flash:", strlen("flash:")) == 0) { - updater::utils::DoReboot("flash", argv[1] + strlen("flash:")); + } else if (strncmp(argv[1], "flashd:", strlen("flashd:")) == 0) { + updater::utils::DoReboot("flashd", argv[1] + strlen("flashd:")); } else { - updater::LOG(updater::INFO) << "param must be updater/flash!"; + updater::LOG(updater::INFO) << "param must be updater/flashd!"; } } return 0; diff --git a/utils/utils.cpp b/utils/utils.cpp index 4f2ead20..fe205e4b 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -178,7 +178,7 @@ void DoReboot(const std::string& rebootTarget, const std::string &extData) if (rebootTarget == "updater" && strcmp(msg.command, "boot_updater") != 0) { result = strcpy_s(msg.command, maxCommandSize, "boot_updater"); msg.command[maxCommandSize] = 0; - } else if (rebootTarget == "flash" && strcmp(msg.command, "flash") != 0) { + } else if (rebootTarget == "flashd" && strcmp(msg.command, "flashd") != 0) { result = strcpy_s(msg.command, maxCommandSize, "boot_flash"); msg.command[maxCommandSize] = 0; } else if (rebootTarget == "bootloader" && strcmp(msg.command, "boot_loader") != 0) { -- Gitee From 6ecc28b980e744ff020b56ba4f6ad42b52807348 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Thu, 11 Nov 2021 15:07:06 +0800 Subject: [PATCH 51/94] updater: fix gn format Signed-off-by: xionglei6 --- test/unittest/BUILD.gn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 9cd5a399..5a7a54c8 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -44,8 +44,8 @@ ohos_unittest("updater_unittest") { "applypatch_test/transfer_manager_unittest.cpp", "diffpatch/bzip2_unittest.cpp", "diffpatch/diffpatch_unittest.cpp", - "flashd_test/flash_service_unittest.cpp", "flashd_test/flash_host_unittest.cpp", + "flashd_test/flash_service_unittest.cpp", "fs_manager/do_partition_unittest.cpp", "log_test/log_unittest.cpp", "misc_info_test/misc_info_unittest.cpp", @@ -96,8 +96,8 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/flashd/blockdevice.cpp", "//base/update/updater/services/flashd/daemon/daemon_updater.cpp", "//base/update/updater/services/flashd/daemon/flashd_main.cpp", - "//base/update/updater/services/flashd/host/host_updater.cpp", "//base/update/updater/services/flashd/flash_service.cpp", + "//base/update/updater/services/flashd/host/host_updater.cpp", "//base/update/updater/services/flashd/partition.cpp", "//base/update/updater/services/fs_manager/cmp_partition.cpp", "//base/update/updater/services/fs_manager/do_partition.cpp", -- Gitee From 4e060b7fccc32849bbf12e998a1b23d15eef619c Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Tue, 16 Nov 2021 10:19:31 +0800 Subject: [PATCH 52/94] updater: add hdc to updater Signed-off-by: xionglei6 --- services/etc/init.cfg | 4 +- services/flashd/BUILD.gn | 184 ++- services/flashd/common/async_cmd.cpp | 189 +++ services/flashd/common/async_cmd.h | 64 + services/flashd/common/auth.cpp | 488 ++++++ services/flashd/common/auth.h | 37 + services/flashd/common/base.cpp | 1249 ++++++++++++++++ services/flashd/common/base.h | 146 ++ services/flashd/common/channel.cpp | 434 ++++++ services/flashd/common/channel.h | 76 + services/flashd/common/common.h | 79 + services/flashd/common/debug.cpp | 104 ++ services/flashd/common/debug.h | 28 + services/flashd/common/define.h | 98 ++ services/flashd/common/define_plus.h | 340 +++++ services/flashd/common/file.cpp | 195 +++ services/flashd/common/file.h | 39 + services/flashd/common/file_descriptor.cpp | 166 +++ services/flashd/common/file_descriptor.h | 58 + services/flashd/common/forward.cpp | 789 ++++++++++ services/flashd/common/forward.h | 107 ++ services/flashd/common/serial_struct.h | 88 ++ services/flashd/common/serial_struct_define.h | 1314 +++++++++++++++++ services/flashd/common/session.cpp | 1062 +++++++++++++ services/flashd/common/session.h | 183 +++ services/flashd/common/task.cpp | 99 ++ services/flashd/common/task.h | 57 + services/flashd/common/tcp.cpp | 98 ++ services/flashd/common/tcp.h | 43 + services/flashd/common/transfer.cpp | 417 ++++++ services/flashd/common/transfer.h | 114 ++ services/flashd/common/usb.cpp | 144 ++ services/flashd/common/usb.h | 41 + services/flashd/daemon/daemon.cpp | 346 +++++ services/flashd/daemon/daemon.h | 47 + services/flashd/daemon/daemon_app.cpp | 151 ++ services/flashd/daemon/daemon_app.h | 38 + services/flashd/daemon/daemon_common.h | 41 + services/flashd/daemon/daemon_forward.cpp | 82 + services/flashd/daemon/daemon_forward.h | 31 + services/flashd/daemon/daemon_tcp.cpp | 151 ++ services/flashd/daemon/daemon_tcp.h | 40 + services/flashd/daemon/daemon_unity.cpp | 305 ++++ services/flashd/daemon/daemon_unity.h | 48 + services/flashd/daemon/daemon_usb.cpp | 498 +++++++ services/flashd/daemon/daemon_usb.h | 62 + services/flashd/daemon/flashd_main.cpp | 9 +- services/flashd/daemon/jdwp.cpp | 279 ++++ services/flashd/daemon/jdwp.h | 59 + services/flashd/daemon/main.cpp | 197 +++ services/flashd/daemon/shell.cpp | 217 +++ services/flashd/daemon/shell.h | 47 + services/flashd/daemon/usb_ffs.h | 218 +++ services/flashd/host/client.cpp | 371 +++++ services/flashd/host/client.h | 59 + services/flashd/host/host_app.cpp | 177 +++ services/flashd/host/host_app.h | 34 + services/flashd/host/host_common.h | 37 + services/flashd/host/host_forward.cpp | 26 + services/flashd/host/host_forward.h | 29 + services/flashd/host/host_tcp.cpp | 166 +++ services/flashd/host/host_tcp.h | 38 + services/flashd/host/host_unity.cpp | 155 ++ services/flashd/host/host_unity.h | 51 + services/flashd/host/host_updater.cpp | 20 +- services/flashd/host/host_updater.h | 1 - services/flashd/host/host_usb.cpp | 550 +++++++ services/flashd/host/host_usb.h | 66 + services/flashd/host/main.cpp | 323 ++++ services/flashd/host/server.cpp | 795 ++++++++++ services/flashd/host/server.h | 64 + services/flashd/host/server_for_client.cpp | 674 +++++++++ services/flashd/host/server_for_client.h | 60 + services/flashd/host/translate.cpp | 248 ++++ services/flashd/host/translate.h | 31 + services/updater_binary/main.cpp | 2 +- test/unittest/BUILD.gn | 11 +- .../flashd_test/flash_host_unittest.cpp | 6 - utils/utils.cpp | 2 + 79 files changed, 15355 insertions(+), 41 deletions(-) create mode 100755 services/flashd/common/async_cmd.cpp create mode 100755 services/flashd/common/async_cmd.h create mode 100755 services/flashd/common/auth.cpp create mode 100755 services/flashd/common/auth.h create mode 100755 services/flashd/common/base.cpp create mode 100755 services/flashd/common/base.h create mode 100755 services/flashd/common/channel.cpp create mode 100755 services/flashd/common/channel.h create mode 100755 services/flashd/common/common.h create mode 100755 services/flashd/common/debug.cpp create mode 100755 services/flashd/common/debug.h create mode 100755 services/flashd/common/define.h create mode 100755 services/flashd/common/define_plus.h create mode 100755 services/flashd/common/file.cpp create mode 100755 services/flashd/common/file.h create mode 100755 services/flashd/common/file_descriptor.cpp create mode 100755 services/flashd/common/file_descriptor.h create mode 100755 services/flashd/common/forward.cpp create mode 100755 services/flashd/common/forward.h create mode 100755 services/flashd/common/serial_struct.h create mode 100755 services/flashd/common/serial_struct_define.h create mode 100755 services/flashd/common/session.cpp create mode 100755 services/flashd/common/session.h create mode 100755 services/flashd/common/task.cpp create mode 100755 services/flashd/common/task.h create mode 100755 services/flashd/common/tcp.cpp create mode 100755 services/flashd/common/tcp.h create mode 100755 services/flashd/common/transfer.cpp create mode 100755 services/flashd/common/transfer.h create mode 100755 services/flashd/common/usb.cpp create mode 100755 services/flashd/common/usb.h create mode 100755 services/flashd/daemon/daemon.cpp create mode 100755 services/flashd/daemon/daemon.h create mode 100755 services/flashd/daemon/daemon_app.cpp create mode 100755 services/flashd/daemon/daemon_app.h create mode 100755 services/flashd/daemon/daemon_common.h create mode 100755 services/flashd/daemon/daemon_forward.cpp create mode 100755 services/flashd/daemon/daemon_forward.h create mode 100755 services/flashd/daemon/daemon_tcp.cpp create mode 100755 services/flashd/daemon/daemon_tcp.h create mode 100755 services/flashd/daemon/daemon_unity.cpp create mode 100755 services/flashd/daemon/daemon_unity.h create mode 100755 services/flashd/daemon/daemon_usb.cpp create mode 100755 services/flashd/daemon/daemon_usb.h create mode 100755 services/flashd/daemon/jdwp.cpp create mode 100755 services/flashd/daemon/jdwp.h create mode 100755 services/flashd/daemon/main.cpp create mode 100755 services/flashd/daemon/shell.cpp create mode 100755 services/flashd/daemon/shell.h create mode 100755 services/flashd/daemon/usb_ffs.h create mode 100755 services/flashd/host/client.cpp create mode 100755 services/flashd/host/client.h create mode 100755 services/flashd/host/host_app.cpp create mode 100755 services/flashd/host/host_app.h create mode 100755 services/flashd/host/host_common.h create mode 100755 services/flashd/host/host_forward.cpp create mode 100755 services/flashd/host/host_forward.h create mode 100755 services/flashd/host/host_tcp.cpp create mode 100755 services/flashd/host/host_tcp.h create mode 100755 services/flashd/host/host_unity.cpp create mode 100755 services/flashd/host/host_unity.h create mode 100755 services/flashd/host/host_usb.cpp create mode 100755 services/flashd/host/host_usb.h create mode 100755 services/flashd/host/main.cpp create mode 100755 services/flashd/host/server.cpp create mode 100755 services/flashd/host/server.h create mode 100755 services/flashd/host/server_for_client.cpp create mode 100755 services/flashd/host/server_for_client.h create mode 100755 services/flashd/host/translate.cpp create mode 100755 services/flashd/host/translate.h diff --git a/services/etc/init.cfg b/services/etc/init.cfg index cefe21d4..a1f12f5d 100755 --- a/services/etc/init.cfg +++ b/services/etc/init.cfg @@ -14,9 +14,11 @@ "mkdir /system", "mkdir /vendor", "mkdir /tmp", + "mkdir /param", "mount tmpfs tmpfs /tmp", "chown 0 2000 /tmp", "chmod 0755 /tmp", + "chmod 0755 /param", "mkdir /dev/usb-ffs 0770 shell shell", "mkdir /dev/usb-ffs/hdc 0770 shell shell", "mkdir /dev/usb-ffs/hdc 0770 shell shell", @@ -40,6 +42,7 @@ "write /config/usb_gadget/g1/configs/b.1/MaxPower 500", "symlink /config/usb_gadget/g1/configs/b.1 /config/usb_gadget/g1/os_desc/b.1", "mount functionfs hdc /dev/usb-ffs/hdc uid=2000,gid=2000", + "load_persist_params ", "setparam sys.usb.controller 100e0000.hidwc3_0", "setparam sys.usb.config hdc", "setparam sys.usb.configfs 1" @@ -65,7 +68,6 @@ "path" : ["/bin/updater"], "uid" : 0, "gid" : 0, - "once" : 1, "importance" : 0, "caps" : [0, 1] }, { diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn index 91407725..d0019f88 100755 --- a/services/flashd/BUILD.gn +++ b/services/flashd/BUILD.gn @@ -13,6 +13,84 @@ import("//build/ohos.gni") +FLASHD_HDC_PATH = "//base/update/updater/services/flashd" + +common_sources = [ + "${FLASHD_HDC_PATH}/common/async_cmd.cpp", + "${FLASHD_HDC_PATH}/common/auth.cpp", + "${FLASHD_HDC_PATH}/common/base.cpp", + "${FLASHD_HDC_PATH}/common/channel.cpp", + "${FLASHD_HDC_PATH}/common/debug.cpp", + "${FLASHD_HDC_PATH}/common/file.cpp", + "${FLASHD_HDC_PATH}/common/file_descriptor.cpp", + "${FLASHD_HDC_PATH}/common/forward.cpp", + "${FLASHD_HDC_PATH}/common/session.cpp", + "${FLASHD_HDC_PATH}/common/task.cpp", + "${FLASHD_HDC_PATH}/common/tcp.cpp", + "${FLASHD_HDC_PATH}/common/transfer.cpp", + "${FLASHD_HDC_PATH}/common/usb.cpp", +] + +config("flashd_hdc_config") { + include_dirs = [ "${FLASHD_HDC_PATH}/common" ] + cflags_cc = [ "-std=c++17" ] +} + +ohos_source_set("flashd_deamon") { + sources = [ + "${FLASHD_HDC_PATH}/daemon/daemon.cpp", + "${FLASHD_HDC_PATH}/daemon/daemon_app.cpp", + "${FLASHD_HDC_PATH}/daemon/daemon_forward.cpp", + "${FLASHD_HDC_PATH}/daemon/daemon_tcp.cpp", + "${FLASHD_HDC_PATH}/daemon/daemon_unity.cpp", + "${FLASHD_HDC_PATH}/daemon/daemon_usb.cpp", + "${FLASHD_HDC_PATH}/daemon/jdwp.cpp", + "${FLASHD_HDC_PATH}/daemon/shell.cpp", + ] + + sources += common_sources + + defines = [ + "HARMONY_PROJECT", + "HDC_SUPPORT_FLASHD", + ] + + configs = [ ":flashd_hdc_config" ] + + deps = [ + "//third_party/libuv:uv_static", + "//third_party/lz4:liblz4_static", + "//third_party/openssl:libcrypto_static", + "//utils/native/base:utils", + ] + + if (use_musl) { + deps += [ + "//base/startup/init_lite/interfaces/innerkits/reboot:libreboot_static", + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", + ] + } + + include_dirs = [ + "${FLASHD_HDC_PATH}/daemon", + "//base/update/updater/services/flashd", + "//base/update/updater/services/flashd/daemon", + "//base/update/updater/services/flashd/common", + "//base/update/updater/services/flashd/host", + "//utils/native/base/include", + "//third_party/lz4/lib", + "//third_party/openssl/include", + "//third_party/libuv", + ] + + if (use_musl) { + include_dirs += [ + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include", + "//base/startup/init_lite/interfaces/innerkits/include", + ] + } +} + ohos_static_library("libflashd") { sources = [ "//base/update/updater/services/flashd/blockdevice.cpp", @@ -31,6 +109,7 @@ ohos_static_library("libflashd") { ] deps = [ + ":flashd_deamon", "//base/update/updater/interfaces/kits/misc_info:libmiscinfo", "//base/update/updater/services/applypatch:libapplypatch", "//base/update/updater/services/diffpatch/patch:libpatch", @@ -39,7 +118,6 @@ ohos_static_library("libflashd") { "//base/update/updater/services/package:libupdaterpackage", "//base/update/updater/services/script:libupdaterscript", "//base/update/updater/utils:libutils", - "//developtools/hdc_standard:hdc_deamon_flashd", "//third_party/bzip2:libbz2", "//third_party/cJSON:cjson_static", "//third_party/libuv:uv_static", @@ -50,8 +128,8 @@ ohos_static_library("libflashd") { ] include_dirs = [ - "//developtools/hdc_standard/src/daemon", - "//developtools/hdc_standard/src/common", + "${FLASHD_HDC_PATH}/daemon", + "${FLASHD_HDC_PATH}/common", "//base/update/updater/services", "//base/update/updater/services/flashd", "//base/update/updater/services/flashd/daemon", @@ -73,6 +151,106 @@ ohos_static_library("libflashd") { part_name = "updater" } +ohos_executable("ohflash") { + libs = [] + configs = [ ":flashd_hdc_config" ] + defines = [ + "HDC_HOST", + "HARMONY_PROJECT", + ] + if (is_mac) { + defines += [ "HOST_MAC" ] + } + cflags_cc = [ + "-Wno-error", + "-Wno-error=unused-variable", + "-Wno-unused-variable", + ] + sources = [ + "${FLASHD_HDC_PATH}/host/client.cpp", + "${FLASHD_HDC_PATH}/host/host_app.cpp", + "${FLASHD_HDC_PATH}/host/host_forward.cpp", + "${FLASHD_HDC_PATH}/host/host_tcp.cpp", + "${FLASHD_HDC_PATH}/host/host_unity.cpp", + "${FLASHD_HDC_PATH}/host/host_usb.cpp", + "${FLASHD_HDC_PATH}/host/main.cpp", + "${FLASHD_HDC_PATH}/host/server.cpp", + "${FLASHD_HDC_PATH}/host/server_for_client.cpp", + "${FLASHD_HDC_PATH}/host/translate.cpp", + "${FLASHD_HDC_PATH}/host/host_updater.cpp", + ] + sources += common_sources + + deps = [ + "//third_party/libusb:libusb", + "//third_party/libuv:uv_static", + "//third_party/lz4:liblz4_static", + "//third_party/openssl:libcrypto_static", + "//utils/native/base:utilsecurec", + ] + + deps += [ + "//third_party/libusb:libusb", + ] + + include_dirs = [ + "${FLASHD_HDC_PATH}/host", + "//utils/native/base/include", + "//third_party/lz4/lib", + "//third_party/openssl/include", + "//third_party/libuv", + ] + + if(is_mingw) { + static_link = true + defines += [ "_WIN32" ] + defines += [ "WIN32_LEAN_AND_MEAN" ] + libs += [ "setupapi" ] + } + + if(is_linux) { + static_link = true + deps += [ "//third_party/openssl:libcrypto_static" ] + } + + subsystem_name = "updater" + part_name = "updater" +} + + +group("flashhost_target_standard") { + deps = [ + ":ohflash", + ] +} + +group("flashhost_target_standard_linux") { + deps = [ + ":ohflash(//build/toolchain/linux:clang_x64)", + ] +} + +group("flashhost_target_standard_mingw") { + deps = [ + ":ohflash(//build/toolchain/mingw:mingw_x86_64)", + ] +} + +group("flashhost_target_standard_all") { + deps = [ + ":flashhost_target_standard", + ":flashhost_target_standard_linux", + ":flashhost_target_standard_mingw", + ] +} + +group("flashhost_target_standard_windows") { + deps = [ + ":flashhost_target_standard", + ":flashhost_target_standard_mingw", + ] +} + group("updater_flashd") { deps = [ ":libflashd" ] } diff --git a/services/flashd/common/async_cmd.cpp b/services/flashd/common/async_cmd.cpp new file mode 100755 index 00000000..43d5f1a9 --- /dev/null +++ b/services/flashd/common/async_cmd.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "async_cmd.h" +#define PIPE_READ 0 +#define PIPE_WRITE 1 + +namespace Hdc { +// Do not add thread-specific init op in the following methods as it's running in child thread. +AsyncCmd::AsyncCmd() +{ + Base::ZeroStruct(stdinPipe); + Base::ZeroStruct(stdoutPipe); + Base::ZeroStruct(stderrPipe); + Base::ZeroStruct(proc); + Base::ZeroStruct(procOptions); + running = false; + loop = nullptr; +} + +AsyncCmd::~AsyncCmd() +{ + WRITE_LOG(LOG_DEBUG, "~AsyncCmd"); +}; + +bool AsyncCmd::ReadyForRelease() const +{ + return !running; +} + +// manual stop will not trigger ExitCallback, we call it +void AsyncCmd::DoRelease() +{ + if (hasStop || !running) { + return; + } + hasStop = true; // must set here to deny repeate release + uv_process_kill(&proc, SIGKILL); + WRITE_LOG(LOG_DEBUG, "AsyncCmd::DoRelease finish"); +} + +void AsyncCmd::ChildReadCallback(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) +{ + AsyncCmd *thisClass = (AsyncCmd *)stream->data; + if (nread <= 0) { // stdout and stderr + WRITE_LOG(LOG_DEBUG, "Read ShellChildProcess failed %s", uv_err_name(nread)); + } else { + if (thisClass->options & OPTION_READBACK_OUT) { + thisClass->cmdResult = buf->base; + if (!thisClass->resultCallback(false, 0, thisClass->cmdResult)) { + uv_process_kill(&thisClass->proc, SIGKILL); + uv_read_stop(stream); + } + thisClass->cmdResult = STRING_EMPTY; + } else { // output all when finish + thisClass->cmdResult += buf->base; + } + } + delete[] buf->base; +} + +void AsyncCmd::ExitCallback(uv_process_t *req, int64_t exitStatus, int tersignal) +{ + auto funcReqClose = [](uv_handle_t *handle) -> void { + AsyncCmd *thisClass = (AsyncCmd *)handle->data; + if (--thisClass->uvRef == 0) { + thisClass->running = false; + } + }; + AsyncCmd *thisClass = (AsyncCmd *)req->data; + thisClass->hasStop = true; // callback maybe call dorelease, so deny repeate ExitCallback + + thisClass->resultCallback(true, exitStatus, thisClass->cmdResult); + WRITE_LOG(LOG_DEBUG, "AsyncCmd::ExitCallback"); + thisClass->uvRef = 4; + Base::TryCloseHandle((uv_handle_t *)&thisClass->stdinPipe, true, funcReqClose); + Base::TryCloseHandle((uv_handle_t *)&thisClass->stdoutPipe, true, funcReqClose); + Base::TryCloseHandle((uv_handle_t *)&thisClass->stderrPipe, true, funcReqClose); + Base::TryCloseHandle((uv_handle_t *)req, true, funcReqClose); + thisClass->cmdResult = STRING_EMPTY; +} + +bool AsyncCmd::Initial(uv_loop_t *loopIn, const CmdResultCallback callback, uint32_t optionsIn) +{ + if (running) { + return false; + } + loop = loopIn; + resultCallback = callback; + options = optionsIn; + return true; +} + +bool AsyncCmd::ExecuteCommand(const string &command) +{ + string cmd = command; + Base::Trim(cmd, "\""); + if (!(options & OPTION_COMMAND_ONETIME)) { + if (StartProcess() < 0) { + return false; + } + if (options & OPTION_APPEND_NEWLINE) { + cmd += "\n"; + } + Base::SendToStream((uv_stream_t *)&stdinPipe, (uint8_t *)cmd.c_str(), cmd.size() + 1); + } else { + if (StartProcess(cmd) < 0) { + return false; + } + } + return true; +} + +int AsyncCmd::StartProcess(string command) +{ + constexpr auto countStdIOCount = 3; + char **ppShellArgs = nullptr; + string shellPath = Base::GetShellPath(); + uv_stdio_container_t stdioShellProc[countStdIOCount]; + while (true) { + uv_pipe_init(loop, &stdinPipe, 1); + uv_pipe_init(loop, &stdoutPipe, 1); + uv_pipe_init(loop, &stderrPipe, 1); + stdinPipe.data = this; + stdoutPipe.data = this; + stderrPipe.data = this; + procOptions.stdio = stdioShellProc; + procOptions.stdio[STDIN_FILENO].flags = (uv_stdio_flags)(UV_CREATE_PIPE | UV_READABLE_PIPE); + procOptions.stdio[STDIN_FILENO].data.stream = (uv_stream_t *)&stdinPipe; + procOptions.stdio[STDOUT_FILENO].flags = (uv_stdio_flags)(UV_CREATE_PIPE | UV_WRITABLE_PIPE); + procOptions.stdio[STDOUT_FILENO].data.stream = (uv_stream_t *)&stdoutPipe; + procOptions.stdio[STDERR_FILENO].flags = (uv_stdio_flags)(UV_CREATE_PIPE | UV_WRITABLE_PIPE); + procOptions.stdio[STDERR_FILENO].data.stream = (uv_stream_t *)&stderrPipe; + procOptions.stdio_count = countStdIOCount; + procOptions.file = shellPath.c_str(); + procOptions.exit_cb = ExitCallback; + + if (command.size() > 0) { + constexpr auto args = 4; + ppShellArgs = new char *[args]; + const string shellCommandFlag = "-c"; + ppShellArgs[0] = (char *)shellPath.c_str(); + ppShellArgs[1] = (char *)shellCommandFlag.c_str(); + ppShellArgs[args - CMD_ARG1_COUNT] = (char *)command.c_str(); + ppShellArgs[args - 1] = nullptr; + } else { + ppShellArgs = new char *[CMD_ARG1_COUNT]; + ppShellArgs[0] = (char *)shellPath.c_str(); + ppShellArgs[1] = nullptr; + } + procOptions.args = ppShellArgs; + proc.data = this; + + if (uv_spawn(loop, &proc, &procOptions)) { + WRITE_LOG(LOG_FATAL, "Spawn shell process failed"); + break; + } + if (uv_read_start((uv_stream_t *)&stdoutPipe, Base::AllocBufferCallback, ChildReadCallback)) { + break; + } + if (uv_read_start((uv_stream_t *)&stderrPipe, Base::AllocBufferCallback, ChildReadCallback)) { + break; + } + running = true; + break; + } + if (ppShellArgs) { + delete[] ppShellArgs; + } + if (!running) { + // failed + resultCallback(true, -1, "Start process failed"); + return -1; + } else { + return 0; + } +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/async_cmd.h b/services/flashd/common/async_cmd.h new file mode 100755 index 00000000..f7772282 --- /dev/null +++ b/services/flashd/common/async_cmd.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_ASYNC_CMD_H +#define HDC_ASYNC_CMD_H +#include "common.h" + +namespace Hdc { +class AsyncCmd { +public: + AsyncCmd(); + virtual ~AsyncCmd(); + enum AsyncCmdOption { + OPTION_APPEND_NEWLINE = 1, + OPTION_COMMAND_ONETIME = 2, + OPTION_READBACK_OUT = 4, + USB_OPTION_RESERVE8 = 8, + }; + // 1)is finish 2)exitStatus 3)resultString(maybe empty) + using CmdResultCallback = std::function; + static uint32_t GetDefaultOption() + { + return OPTION_APPEND_NEWLINE | OPTION_COMMAND_ONETIME; + } + // uv_loop_t loop is given to uv_spawn, which can't be const + bool Initial(uv_loop_t *loopIn, const CmdResultCallback callback, uint32_t optionsIn = GetDefaultOption()); + void DoRelease(); // Release process resources + bool ExecuteCommand(const string &command); + bool ReadyForRelease() const; + +private: + int StartProcess(string command = STRING_EMPTY); + // uv_read_cb callback 1st parameter can't be changed, const can't be added + static void ChildReadCallback(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); + // uv_exit_cb callback 1st parameter can't be changed, const can't be added + static void ExitCallback(uv_process_t *req, int64_t exitStatus, int tersignal); + + uv_loop_t *loop; + // loop is given to uv_spawn, which can't be const + uv_pipe_t stdinPipe; + uv_pipe_t stdoutPipe; + uv_pipe_t stderrPipe; + uv_process_t proc; + uv_process_options_t procOptions; + CmdResultCallback resultCallback; + string cmdResult; + bool running; + bool hasStop = false; + uint32_t options = 0; + uint8_t uvRef = 0; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/common/auth.cpp b/services/flashd/common/auth.cpp new file mode 100755 index 00000000..50f148b4 --- /dev/null +++ b/services/flashd/common/auth.cpp @@ -0,0 +1,488 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "auth.h" +#include +#include +#include +#include +#include + +using namespace Hdc; +#define BIGNUMTOBIT 32 + +namespace HdcAuth { +// ---------------------------------------Cheat compiler--------------------------------------------------------- +#ifdef HDC_HOST + +bool AuthVerify(uint8_t *token, uint8_t *sig, int siglen) +{ + return false; +}; +bool PostUIConfirm(string publicKey) +{ + return false; +} + +#else // daemon + +bool GenerateKey(const char *file) +{ + return false; +}; +int AuthSign(void *rsa, const unsigned char *token, size_t tokenSize, void *sig) +{ + return 0; +}; +int GetPublicKeyFileBuf(unsigned char *data, size_t len) +{ + return 0; +} + +#endif +// ------------------------------------------------------------------------------------------------ + +const uint32_t RSANUMBYTES = 256; // 2048 bit key length +const uint32_t RSANUMWORDS = (RSANUMBYTES / sizeof(uint32_t)); +struct RSAPublicKey { + int wordModulusSize; // Length of n[] in number of uint32_t */ + uint32_t rsaN0inv; // -1 / n[0] mod 2^32 + uint32_t modulus[RSANUMWORDS]; // modulus as little endian array + uint32_t rr[RSANUMWORDS]; // R^2 as little endian array + int exponent; // 3 or 65537 +}; + +#ifdef HDC_HOST +// Convert OpenSSL RSA private key to pre-computed RSAPublicKey format +int RSA2RSAPublicKey(RSA *rsa, RSAPublicKey *publicKey) +{ + int result = 1; + unsigned int i; + BN_CTX *ctx = BN_CTX_new(); + BIGNUM *r32 = BN_new(); + BIGNUM *rsaRR = BN_new(); + BIGNUM *rsaR = BN_new(); + BIGNUM *rsaRem = BN_new(); + BIGNUM *rsaN0inv = BN_new(); +#ifdef OPENSSL_IS_BORINGSSL + // boringssl + BIGNUM *n = BN_new(); + BN_copy(n, rsa->n); + publicKey->exponent = BN_get_word(rsa->e); +#else + // openssl +#if OPENSSL_VERSION_NUMBER >= 0x10100005L + BIGNUM *n = (BIGNUM *)RSA_get0_n(rsa); + publicKey->exponent = BN_get_word(RSA_get0_e(rsa)); +#else + BIGNUM *n = BN_new(); + BN_copy(n, rsa->n); + publicKey->exponent = BN_get_word(rsa->e); +#endif + +#endif // OPENSSL_IS_BORINGSSL + while (true) { + if (RSA_size(rsa) != RSANUMBYTES) { + result = 0; + break; + } + + BN_set_bit(r32, BIGNUMTOBIT); + BN_set_bit(rsaR, RSANUMWORDS * BIGNUMTOBIT); + BN_mod_sqr(rsaRR, rsaR, n, ctx); + BN_div(nullptr, rsaRem, n, r32, ctx); + BN_mod_inverse(rsaN0inv, rsaRem, r32, ctx); + publicKey->wordModulusSize = RSANUMWORDS; + publicKey->rsaN0inv = 0 - BN_get_word(rsaN0inv); + for (i = 0; i < RSANUMWORDS; ++i) { + BN_div(rsaRR, rsaRem, rsaRR, r32, ctx); + publicKey->rr[i] = BN_get_word(rsaRem); + BN_div(n, rsaRem, n, r32, ctx); + publicKey->modulus[i] = BN_get_word(rsaRem); + } + break; + } + + BN_free(rsaR); + BN_free(rsaRR); + BN_free(n); + BN_free(r32); + BN_free(rsaN0inv); + BN_free(rsaRem); + BN_CTX_free(ctx); + return result; +} + +int GetUserInfo(char *buf, size_t len) +{ + char hostname[BUF_SIZE_DEFAULT]; + char username[BUF_SIZE_DEFAULT]; + uv_passwd_t pwd; + int ret = -1; + size_t bufSize = sizeof(hostname); + if (uv_os_gethostname(hostname, &bufSize) < 0 && EOK != strcpy_s(hostname, sizeof(hostname), "unknown")) { + return ERR_API_FAIL; + } + if (!uv_os_get_passwd(&pwd) && !strcpy_s(username, sizeof(username), pwd.username)) { + ret = 0; + } + uv_os_free_passwd(&pwd); + if (ret < 0 && EOK != strcpy_s(username, sizeof(username), "unknown")) { + return ERR_API_FAIL; + } + if (snprintf_s(buf, len, len - 1, " %s@%s", username, hostname) < 0) { + return ERR_BUF_OVERFLOW; + } + return RET_SUCCESS; +} + +int WritePublicKeyfile(RSA *private_key, const char *private_key_path) +{ + RSAPublicKey publicKey; + char info[BUF_SIZE_DEFAULT]; + int ret = 0; + string path = private_key_path + string(".pub"); + + ret = RSA2RSAPublicKey(private_key, &publicKey); + if (!ret) { + WRITE_LOG(LOG_DEBUG, "Failed to convert to publickey\n"); + return 0; + } + vector vec = Base::Base64Encode((const uint8_t *)&publicKey, sizeof(RSAPublicKey)); + if (!vec.size()) { + return 0; + } + GetUserInfo(info, sizeof(info)); + vec.insert(vec.end(), (uint8_t *)info, (uint8_t *)info + strlen(info)); + ret = Base::WriteBinFile(path.c_str(), vec.data(), vec.size(), true); + return ret >= 0 ? 1 : 0; +} + +bool GenerateKey(const char *file) +{ + EVP_PKEY *publicKey = EVP_PKEY_new(); + BIGNUM *exponent = BN_new(); + RSA *rsa = RSA_new(); + mode_t old_mask; + FILE *fKey = nullptr; + bool ret = false; + + while (true) { + WRITE_LOG(LOG_DEBUG, "generate_key '%s'\n", file); + if (!publicKey || !exponent || !rsa) { + WRITE_LOG(LOG_DEBUG, "Failed to allocate key"); + break; + } + + BN_set_word(exponent, RSA_F4); + RSA_generate_key_ex(rsa, 2048, exponent, nullptr); + EVP_PKEY_set1_RSA(publicKey, rsa); + old_mask = umask(077); // 077:permission + + fKey = fopen(file, "w"); + if (!fKey) { + WRITE_LOG(LOG_DEBUG, "Failed to open '%s'\n", file); + umask(old_mask); + break; + } + umask(old_mask); + if (!PEM_write_PrivateKey(fKey, publicKey, nullptr, nullptr, 0, nullptr, nullptr)) { + WRITE_LOG(LOG_DEBUG, "Failed to write key"); + break; + } + if (!WritePublicKeyfile(rsa, file)) { + WRITE_LOG(LOG_DEBUG, "Failed to write public key"); + break; + } + ret = true; + break; + } + + RSA_free(rsa); + EVP_PKEY_free(publicKey); + BN_free(exponent); + if (fKey) + fclose(fKey); + return ret; +} + +bool ReadKey(const char *file, list *listPrivateKey) +{ + FILE *f = nullptr; + bool ret = false; + + while (true) { + if (!(f = fopen(file, "r"))) { + break; + } + RSA *rsa = RSA_new(); + if (!PEM_read_RSAPrivateKey(f, &rsa, nullptr, nullptr)) { + RSA_free(rsa); + break; + } + listPrivateKey->push_back((void *)rsa); + ret = true; + break; + } + if (f) { + fclose(f); + } + return ret; +} + +int GetUserKeyPath(string &path) +{ + struct stat status; + const char harmoneyPath[] = ".harmony"; + const char hdcKeyFile[] = "hdckey"; + char buf[BUF_SIZE_DEFAULT]; + size_t len = BUF_SIZE_DEFAULT; + // $home + if (uv_os_homedir(buf, &len) < 0) + return false; + path = string(buf) + Base::GetPathSep() + string(harmoneyPath) + Base::GetPathSep(); + if (stat(path.c_str(), &status)) { + uv_fs_t req; + uv_fs_mkdir(nullptr, &req, path.c_str(), 0750, nullptr); // 0750:permission + uv_fs_req_cleanup(&req); + if (req.result < 0) { + WRITE_LOG(LOG_DEBUG, "Cannot mkdir '%s'", path.c_str()); + return false; + } + } + path += hdcKeyFile; + return true; +} + +bool LoadHostUserKey(list *listPrivateKey) +{ + struct stat status; + string path; + if (!GetUserKeyPath(path)) { + return false; + } + if (stat(path.c_str(), &status) == -1) { + if (!GenerateKey(path.c_str())) { + WRITE_LOG(LOG_DEBUG, "Failed to generate new key"); + return false; + } + } + if (!ReadKey(path.c_str(), listPrivateKey)) { + return false; + } + return true; +} + +int AuthSign(void *rsa, const unsigned char *token, size_t tokenSize, void *sig) +{ + unsigned int len; + if (!RSA_sign(NID_sha1, token, tokenSize, (unsigned char *)sig, &len, (RSA *)rsa)) { + return 0; + } + return (int)len; +} + +int GetPublicKeyFileBuf(unsigned char *data, size_t len) +{ + string path; + int ret; + + if (!GetUserKeyPath(path)) { + return 0; + } + path += ".pub"; + ret = Base::ReadBinFile(path.c_str(), (void **)data, len); + if (ret <= 0) { + return 0; + } + data[ret] = '\0'; + return ret + 1; +} + +#else // daemon + +bool RSAPublicKey2RSA(const uint8_t *keyBuf, RSA **key) +{ + const int pubKeyModulusSize = 256; + const int pubKeyModulusSizeWords = pubKeyModulusSize / 4; + + const RSAPublicKey *keyStruct = reinterpret_cast(keyBuf); + bool ret = false; + uint8_t modulusBuffer[pubKeyModulusSize]; + RSA *newKey = RSA_new(); + if (!newKey) { + goto cleanup; + } + if (keyStruct->wordModulusSize != pubKeyModulusSizeWords) { + goto cleanup; + } + if (memcpy_s(modulusBuffer, sizeof(modulusBuffer), keyStruct->modulus, sizeof(modulusBuffer)) != EOK) { + goto cleanup; + } + Base::ReverseBytes(modulusBuffer, sizeof(modulusBuffer)); + +#ifdef OPENSSL_IS_BORINGSSL + // boringssl + newKey->n = BN_bin2bn(modulusBuffer, sizeof(modulusBuffer), nullptr); + newKey->e = BN_new(); + if (!newKey->e || !BN_set_word(newKey->e, keyStruct->exponent) || !newKey->n) { + goto cleanup; + } +#else + // openssl +#if OPENSSL_VERSION_NUMBER >= 0x10100005L + RSA_set0_key(newKey, BN_bin2bn(modulusBuffer, sizeof(modulusBuffer), nullptr), BN_new(), BN_new()); +#else + newKey->n = BN_bin2bn(modulusBuffer, sizeof(modulusBuffer), nullptr); + newKey->e = BN_new(); + if (!newKey->e || !BN_set_word(newKey->e, keyStruct->exponent) || !newKey->n) { + goto cleanup; + } +#endif +#endif + + *key = newKey; + ret = true; + +cleanup: + if (!ret && newKey) { + RSA_free(newKey); + } + return ret; +} + +void ReadDaemonKeys(const char *file, list *listPublicKey) +{ + char buf[BUF_SIZE_DEFAULT2]; + char *sep = nullptr; + int ret; + FILE *f = fopen(file, "re"); + if (!f) { + WRITE_LOG(LOG_DEBUG, "Can't open '%s'", file); + return; + } + while (fgets(buf, sizeof(buf), f)) { + RSAPublicKey *key = new RSAPublicKey(); + if (!key) { + break; + } + sep = strpbrk(buf, " \t"); + if (sep) { + *sep = '\0'; + } + ret = Base::Base64DecodeBuf(reinterpret_cast(buf), strlen(buf), (uint8_t *)key); + if (ret != sizeof(RSAPublicKey)) { + WRITE_LOG(LOG_DEBUG, "%s: Invalid base64 data ret=%d", file, ret); + delete key; + continue; + } + + if (key->wordModulusSize != RSANUMWORDS) { + WRITE_LOG(LOG_DEBUG, "%s: Invalid key len %d\n", file, key->wordModulusSize); + delete key; + continue; + } + listPublicKey->push_back(key); + } + fclose(f); +} + +bool AuthVerify(uint8_t *token, uint8_t *sig, int siglen) +{ + list listPublicKey; + uint8_t authKeyIndex = 0; + void *ptr = nullptr; + int ret = 0; + int childRet = 0; + while (KeylistIncrement(&listPublicKey, authKeyIndex, &ptr)) { + RSA *rsa = nullptr; + if (!RSAPublicKey2RSA((const uint8_t *)ptr, &rsa)) { + break; + } + childRet = RSA_verify(NID_sha1, (const unsigned char *)token, RSA_TOKEN_SIZE, (const unsigned char *)sig, + siglen, rsa); + RSA_free(rsa); + if (childRet) { + ret = 1; + break; + } + } + FreeKey(true, &listPublicKey); + return ret; +} + +void LoadDaemonKey(list *listPublicKey) +{ +#ifdef HDC_PCDEBUG + char keyPaths[][BUF_SIZE_SMALL] = { "/root/.harmony/hdckey.pub" }; +#else + char keyPaths[][BUF_SIZE_SMALL] = { "/hdc_keys", "/data/misc/hdc/hdc_keys" }; +#endif + int num = sizeof(keyPaths) / sizeof(keyPaths[0]); + struct stat buf; + + for (int i = 0; i < num; ++i) { + char *p = keyPaths[i]; + if (!stat(p, &buf)) { + WRITE_LOG(LOG_DEBUG, "Loading keys from '%s'", p); + ReadDaemonKeys(p, listPublicKey); + } + } +} + +bool PostUIConfirm(string publicKey) +{ + // Because the Hi3516 development board has no UI support for the time being, all public keys are received and + // By default, the system UI will record the public key /data/misc/hdc/hdckey/data/misc/hdc/hdckey + return true; +} +#endif // HDC_HOST + +// --------------------------------------common code------------------------------------------ +bool KeylistIncrement(list *listKey, uint8_t &authKeyIndex, void **out) +{ + if (!listKey->size()) { +#ifdef HDC_HOST + LoadHostUserKey(listKey); +#else + LoadDaemonKey(listKey); +#endif + } + if (authKeyIndex == listKey->size()) { + // all finish + return false; + } + auto listIndex = listKey->begin(); + std::advance(listIndex, ++authKeyIndex); + *out = *listIndex; + if (!*out) { + return false; + } + return true; +} + +void FreeKey(bool publicOrPrivate, list *listKey) +{ + for (auto &&v : *listKey) { + if (publicOrPrivate) { + delete (RSAPublicKey *)v; + v = nullptr; + } else { + RSA_free((RSA *)v); + v = nullptr; + } + } + listKey->clear(); +} +} diff --git a/services/flashd/common/auth.h b/services/flashd/common/auth.h new file mode 100755 index 00000000..1e2083b6 --- /dev/null +++ b/services/flashd/common/auth.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_AUTH_H +#define HDC_AUTH_H +#include "common.h" + +// If these functions occupy too high a load, you can consider placing them in a thread for execution, and perform +// subsequent processing in the callback directly after completion. +namespace HdcAuth { +const uint8_t RSA_TOKEN_SIZE = 20; // SHA_DIGEST_LENGTH +// in host out==RSA*, in daemon out=RSAPublicKey* +bool KeylistIncrement(list *listKey, uint8_t &authKeyIndex, void **out); +void FreeKey(bool publicOrPrivate, list *listKey); + +// host +bool GenerateKey(const char *file); +int AuthSign(void *rsa, const unsigned char *token, size_t tokenSize, void *sig); +int GetPublicKeyFileBuf(unsigned char *data, size_t len); + +// daemon +bool AuthVerify(uint8_t *token, uint8_t *sig, int siglen); +bool PostUIConfirm(string pkey); +} + +#endif \ No newline at end of file diff --git a/services/flashd/common/base.cpp b/services/flashd/common/base.cpp new file mode 100755 index 00000000..b0e7f153 --- /dev/null +++ b/services/flashd/common/base.cpp @@ -0,0 +1,1249 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "base.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __MUSL__ +extern "C" { +#include "parameter.h" +} +#endif +using namespace std::chrono; + +namespace Hdc { +namespace Base { + uint8_t g_logLevel = 0; + void SetLogLevel(const uint8_t logLevel) + { + g_logLevel = logLevel; + } + +// Commenting the code will optimize and tune all log codes, and the compilation volume will be greatly reduced +#define ENABLE_DEBUGLOG +#ifdef ENABLE_DEBUGLOG + void GetLogDebugFunctioname(string &debugInfo, int line, string &threadIdString) + { + string tmpString = GetFileNameAny(debugInfo); + debugInfo = StringFormat("%s:%d", tmpString.c_str(), line); + if (g_logLevel < LOG_FULL) { + debugInfo = ""; + threadIdString = ""; + } else { + debugInfo = "[" + debugInfo + "]"; + threadIdString = StringFormat("[%x]", std::hash {}(std::this_thread::get_id())); + } + } + + bool IsWindowsSupportAnsiColor() + { +#ifdef _WIN32 + // Set output mode to handle virtual terminal sequences + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (hOut == INVALID_HANDLE_VALUE) { + return false; + } + DWORD dwMode = 0; + if (!GetConsoleMode(hOut, &dwMode)) { + return false; + } + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if (!SetConsoleMode(hOut, dwMode)) { + return false; + } +#endif + return true; + } + + void GetLogLevelAndTime(uint8_t logLevel, string &logLevelString, string &timeString) + { + system_clock::time_point timeNow = system_clock::now(); // now time + system_clock::duration sinceUnix0 = timeNow.time_since_epoch(); // since 1970 + time_t sSinceUnix0 = duration_cast(sinceUnix0).count(); + std::tm tim = *std::localtime(&sSinceUnix0); + bool enableAnsiColor = false; +#ifdef _WIN32 + enableAnsiColor = IsWindowsSupportAnsiColor(); +#else + enableAnsiColor = true; +#endif + if (enableAnsiColor) { + switch (logLevel) { + case LOG_FATAL: + logLevelString = "\033[1;31mF\033[0m"; + break; + case LOG_INFO: + logLevelString = "\033[1;32mI\033[0m"; + break; + case LOG_WARN: + logLevelString = "\033[1;33mW\033[0m"; + break; + case LOG_DEBUG: + logLevelString = "\033[1;36mD\033[0m"; + break; + default: + logLevelString = "\033[1;36mD\033[0m"; + break; + } + } else { + logLevelString = std::to_string(logLevel); + } + string msTimeSurplus; + if (g_logLevel > LOG_DEBUG) { + const auto sSinceUnix0Rest = duration_cast(sinceUnix0).count() % (TIME_BASE * TIME_BASE); + msTimeSurplus = StringFormat(".%06llu", sSinceUnix0Rest); + } + timeString = StringFormat("%d:%d:%d%s", tim.tm_hour, tim.tm_min, tim.tm_sec, msTimeSurplus.c_str()); + } + + void PrintLogEx(const char *functionName, int line, uint8_t logLevel, const char *msg, ...) + { + if (logLevel > g_logLevel) { + return; + } + string debugInfo; + string logBuf; + string logLevelString; + string threadIdString; + string sep = "\n"; + string timeString; + + va_list vaArgs; + va_start(vaArgs, msg); + string logDetail = Base::StringFormat(msg, vaArgs); + va_end(vaArgs); + if (logDetail.back() == '\n') { + sep = "\r\n"; + } + debugInfo = functionName; + GetLogDebugFunctioname(debugInfo, line, threadIdString); + GetLogLevelAndTime(logLevel, logLevelString, timeString); + logBuf = StringFormat("[%s][%s]%s%s %s%s", logLevelString.c_str(), timeString.c_str(), threadIdString.c_str(), + debugInfo.c_str(), logDetail.c_str(), sep.c_str()); + + printf("%s", logBuf.c_str()); + fflush(stdout); + // logfile, not thread-safe +#ifdef HDC_SUPPORT_FLASHD + FILE *fp = fopen("/tmp/flashd_hdc.log", "a"); +#else + string path = GetTmpDir() + LOG_FILE_NAME; + FILE *fp = fopen(path.c_str(), "a"); +#endif + if (fp == nullptr) { + return; + } + if (fprintf(fp, "%s", logBuf.c_str()) > 0 && fflush(fp)) { + // make ci happy + } + fclose(fp); + return; + } +#else // else ENABLE_DEBUGLOG.If disabled, the entire output code will be optimized by the compiler + void PrintLogEx(uint8_t logLevel, char *msg, ...) + { + } +#endif // ENABLE_DEBUGLOG + + void PrintMessage(const char *fmt, ...) + { + va_list ap; + va_start(ap, fmt); + if (vfprintf(stdout, fmt, ap) > 0) { + fprintf(stdout, "\n"); + } + va_end(ap); + } + + // if can linkwith -lstdc++fs, use std::filesystem::path(path).filename(); + string GetFileNameAny(string &path) + { + string tmpString = path; + size_t tmpNum = tmpString.rfind('/'); + if (tmpNum == std::string::npos) { + tmpNum = tmpString.rfind('\\'); + if (tmpNum == std::string::npos) { + return tmpString; + } + } + tmpString = tmpString.substr(tmpNum + 1, tmpString.size() - tmpNum); + return tmpString; + } + + int GetMaxBufSize() + { + return MAX_SIZE_IOBUF; + } + + void SetTcpOptions(uv_tcp_t *tcpHandle) + { + constexpr int maxBufFactor = 10; + if (!tcpHandle) { + WRITE_LOG(LOG_WARN, "SetTcpOptions nullptr Ptr"); + return; + } + uv_tcp_keepalive(tcpHandle, 1, GLOBAL_TIMEOUT); + // if MAX_SIZE_IOBUF==5k,bufMaxSize at least 40k. It must be set to io 8 times is more appropriate, + // otherwise asynchronous IO is too fast, a lot of IO is wasted on IOloop, transmission speed will decrease + int bufMaxSize = GetMaxBufSize() * maxBufFactor; + uv_recv_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); + uv_send_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); + } + + void ReallocBuf(uint8_t **origBuf, int *nOrigSize, const int indexUsedBuf, int sizeWanted) + { + sizeWanted = GetMaxBufSize(); + int remainLen = *nOrigSize - indexUsedBuf; + // init:0, left less than expected + if (!*nOrigSize || (remainLen < sizeWanted && (*nOrigSize + sizeWanted < sizeWanted * 2))) { + // Memory allocation size is slightly larger than the maximum + int nNewLen = *nOrigSize + sizeWanted + EXTRA_ALLOC_SIZE; + uint8_t *bufPtrOrig = *origBuf; + *origBuf = new uint8_t[nNewLen](); + if (!*origBuf) { + *origBuf = bufPtrOrig; + } else { + *nOrigSize = nNewLen; + if (bufPtrOrig) { + if (memcpy_s(*origBuf, nNewLen, bufPtrOrig, *nOrigSize)) { + WRITE_LOG(LOG_FATAL, "ReallocBuf failed"); + } + delete[] bufPtrOrig; + } + } + uint8_t *buf = static_cast(*origBuf + indexUsedBuf); + Base::ZeroBuf(buf, nNewLen - indexUsedBuf); + } + } + + // As an uv_alloc_cb it must keep the same as prototype + void AllocBufferCallback(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf) + { + const int size = GetMaxBufSize(); + buf->base = (char *)new uint8_t[size](); + if (buf->base) { + buf->len = size - 1; + } + } + + // As an uv_write_cb it must keep the same as prototype + void SendCallback(uv_write_t *req, int status) + { + delete[]((uint8_t *)req->data); + delete req; + } + + // xxx must keep sync with uv_loop_close/uv_walk etc. + bool TryCloseLoop(uv_loop_t *ptrLoop, const char *callerName) + { + // UV_RUN_DEFAULT: Runs the event loop until the reference count drops to zero. Always returns zero. + // UV_RUN_ONCE: Poll for new events once. Note that this function blocks if there are no pending events. + // Returns zero when done (no active handles or requests left), or non-zero if more events are + // expected meaning you should run the event loop again sometime in the future). + // UV_RUN_NOWAIT: Poll for new events once but don't block if there are no pending events. + uint8_t closeRetry = 0; + bool ret = false; + constexpr int maxRetry = 3; + for (closeRetry = 0; closeRetry < maxRetry; ++closeRetry) { + if (uv_loop_close(ptrLoop) == UV_EBUSY) { + if (closeRetry > 2) { // 2 try count + WRITE_LOG(LOG_WARN, "%s close busy,try:%d", callerName, closeRetry); + } + + if (ptrLoop->active_handles >= 2) { + WRITE_LOG(LOG_DEBUG, "TryCloseLoop issue"); + } + auto clearLoopTask = [](uv_handle_t *handle, void *arg) -> void { TryCloseHandle(handle); }; + uv_walk(ptrLoop, clearLoopTask, nullptr); + // If all processing ends, Then return0,this call will block + if (!ptrLoop->active_handles) { + ret = true; + break; + } + if (!uv_run(ptrLoop, UV_RUN_ONCE)) { + ret = true; + break; + } + } else { + ret = true; + break; + } + } + return ret; + } + + // Some handles may not be initialized or activated yet or have been closed, skip the closing process + void TryCloseHandle(const uv_handle_t *handle) + { + TryCloseHandle(handle, nullptr); + } + + void TryCloseHandle(const uv_handle_t *handle, uv_close_cb closeCallBack) + { + TryCloseHandle(handle, false, closeCallBack); + } + + void TryCloseHandle(const uv_handle_t *handle, bool alwaysCallback, uv_close_cb closeCallBack) + { + bool hasCallClose = false; + if (handle->loop && !uv_is_closing(handle)) { + uv_close((uv_handle_t *)handle, closeCallBack); + hasCallClose = true; + } + if (!hasCallClose && alwaysCallback) { + closeCallBack((uv_handle_t *)handle); + } + } + + int SendToStream(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen) + { + if (bufLen > static_cast(HDC_BUF_MAX_BYTES)) { + return ERR_BUF_ALLOC; + } + uint8_t *pDynBuf = new uint8_t[bufLen]; + if (!pDynBuf) { + return ERR_BUF_ALLOC; + } + if (memcpy_s(pDynBuf, bufLen, buf, bufLen)) { + delete[] pDynBuf; + return ERR_BUF_COPY; + } + return SendToStreamEx(handleStream, pDynBuf, bufLen, nullptr, (void *)SendCallback, (void *)pDynBuf); + } + + // handleSend is used for pipe thread sending, set nullptr for tcp, and dynamically allocated by malloc when buf + // is required + int SendToStreamEx(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen, uv_stream_t *handleSend, + const void *finishCallback, const void *pWriteReqData) + { + int ret = -1; + uv_write_t *reqWrite = new uv_write_t(); + if (!reqWrite) { + return 0; + } + uv_buf_t bfr; + while (true) { + reqWrite->data = (void *)pWriteReqData; + bfr.base = (char *)buf; + bfr.len = bufLen; + if (!uv_is_writable(handleStream)) { + delete reqWrite; + break; + } + // handleSend must be a TCP socket or pipe, which is a server or a connection (listening or + // connected state). Bound sockets or pipes will be assumed to be servers. + if (handleSend) { + uv_write2(reqWrite, handleStream, &bfr, 1, handleSend, (uv_write_cb)finishCallback); + } else { + uv_write(reqWrite, handleStream, &bfr, 1, (uv_write_cb)finishCallback); + } + ret = bufLen; + break; + } + return ret; + } + + uint64_t GetRuntimeMSec() + { + struct timespec times = { 0, 0 }; + long time; + clock_gettime(CLOCK_MONOTONIC, ×); + time = times.tv_sec * TIME_BASE + times.tv_nsec / (TIME_BASE * TIME_BASE); + return time; + } + + uint64_t GetRandom(const uint64_t min, const uint64_t max) + { +#ifdef HARMONY_PROJECT + uint64_t ret; + uv_random(nullptr, nullptr, &ret, sizeof(ret), 0, nullptr); +#else + uint64_t ret; + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dis(min, max); + ret = dis(gen); +#endif + return ret; + } + + string GetRandomString(const uint16_t expectedLen) + { + srand(static_cast(GetRandom())); + string ret = string(expectedLen, '0'); + std::stringstream val; + for (auto i = 0; i < expectedLen; ++i) { + val << std::hex << (rand() % BUF_SIZE_MICRO); + } + ret = val.str(); + return ret; + } + + int GetRandomNum(const int min, const int max) + { + return static_cast(GetRandom(min, max)); + } + + int ConnectKey2IPPort(const char *connectKey, char *outIP, uint16_t *outPort) + { + char bufString[BUF_SIZE_TINY] = ""; + if (memcpy_s(bufString, sizeof(bufString), connectKey, sizeof(bufString))) { + return ERR_BUF_COPY; + } + char *p = strchr(bufString, ':'); + if (!p) { + return ERR_PARM_FORMAT; + } + *p = '\0'; + if (!strlen(bufString) || strlen(bufString) > 16) { + return ERR_PARM_SIZE; + } + uint16_t wPort = static_cast(atoi(p + 1)); + if (EOK != strcpy_s(outIP, BUF_SIZE_TINY, bufString)) { + return ERR_BUF_COPY; + } + *outPort = wPort; + return RET_SUCCESS; + } + + // After creating the session worker thread, execute it on the main thread + void FinishWorkThread(uv_work_t *req, int status) + { + // This is operated in the main thread + delete req; + } + + // at the finsh of pFuncAfterThread must free uv_work_t* + // clang-format off + int StartWorkThread(uv_loop_t *loop, uv_work_cb pFuncWorkThread, + uv_after_work_cb pFuncAfterThread, void *pThreadData) + { + uv_work_t *workThread = new uv_work_t(); + if (!workThread) { + return -1; + } + workThread->data = pThreadData; + uv_queue_work(loop, workThread, pFuncWorkThread, pFuncAfterThread); + return 0; + } + // clang-format on + + char **SplitCommandToArgs(const char *cmdStringLine, int *slotIndex) + { + constexpr int extraBufSize = 2; + char **argv; + char *temp = nullptr; + int argc = 0; + char a = 0; + size_t i = 0; + size_t j = 0; + size_t len = 0; + bool isQuoted = false; + bool isText = false; + bool isSpace = false; + + len = strlen(cmdStringLine); + if (len < 1) { + return nullptr; + } + i = ((len + extraBufSize) / extraBufSize) * sizeof(void *) + sizeof(void *); + argv = reinterpret_cast(new char[i + (len + extraBufSize) * sizeof(char)]); + temp = reinterpret_cast((reinterpret_cast(argv)) + i); + argc = 0; + argv[argc] = temp; + isQuoted = false; + isText = false; + isSpace = true; + i = 0; + j = 0; + + while ((a = cmdStringLine[i]) != 0) { + if (isQuoted) { + if (a == '\"') { + isQuoted = false; + } else { + temp[j] = a; + ++j; + } + } else { + switch (a) { + case '\"': + isQuoted = true; + isText = true; + if (isSpace) { + argv[argc] = temp + j; + ++argc; + } + isSpace = false; + break; + case ' ': + case '\t': + case '\n': + case '\r': + if (isText) { + temp[j] = '\0'; + ++j; + } + isText = false; + isSpace = true; + break; + default: + isText = true; + if (isSpace) { + argv[argc] = temp + j; + ++argc; + } + temp[j] = a; + ++j; + isSpace = false; + break; + } + } + ++i; + } + temp[j] = '\0'; + argv[argc] = nullptr; + + (*slotIndex) = argc; + return argv; + } + + bool RunPipeComand(const char *cmdString, char *outBuf, uint16_t sizeOutBuf, bool ignoreTailLf) + { + FILE *pipeHandle = popen(cmdString, "r"); + if (pipeHandle == nullptr) { + return false; + } + int bytesRead = 0; + int bytesOnce = 0; + while (!feof(pipeHandle)) { + bytesOnce = fread(outBuf, 1, sizeOutBuf - bytesRead, pipeHandle); + if (bytesOnce <= 0) { + break; + } + bytesRead += bytesOnce; + } + if (bytesRead && ignoreTailLf) { + if (outBuf[bytesRead - 1] == '\n') { + outBuf[bytesRead - 1] = '\0'; + } + } + pclose(pipeHandle); + return bytesRead; + } + + bool SetHdcProperty(const char *key, const char *value) + { +#ifndef __MUSL__ +#ifdef HDC_PCDEBUG + WRITE_LOG(LOG_DEBUG, "Setproperty, key:%s value:%s", key, value); +#else + string sKey = key; + string sValue = value; + string sBuf = "setprop " + sKey + " " + value; + system(sBuf.c_str()); +#endif +#else + SetParameter(key, value); +#endif + return true; + } + + bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf) + { +#ifndef __MUSL__ +#ifdef HDC_PCDEBUG + WRITE_LOG(LOG_DEBUG, "Getproperty, key:%s value:%s", key, value); +#else + string sKey = key; + string sBuf = "getprop " + sKey; + RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); +#endif +#else + string sKey = key; + string sBuf = "param get " + sKey; + RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); +#endif + value[sizeOutBuf - 1] = '\0'; + return true; + } + + // bufLen == 0: alloc buffer in heap, need free it later + // >0: read max nBuffLen bytes to *buff + // ret value: <0 or bytes read + int ReadBinFile(const char *pathName, void **buf, const int bufLen) + { + uint8_t *pDst = nullptr; + int byteIO = 0; + struct stat statbuf; + int ret = stat(pathName, &statbuf); + if (ret < 0) { + return -1; + } + int nFileSize = statbuf.st_size; + int readMax = 0; + uint8_t dynamicBuf = 0; + ret = -3; + if (bufLen == 0) { + dynamicBuf = 1; + pDst = new uint8_t[nFileSize + 1](); // tail \0 + if (!pDst) { + return -1; + } + readMax = nFileSize; + } else { + if (nFileSize > bufLen) { + return -2; + } + readMax = nFileSize; + pDst = reinterpret_cast(buf); // The first address of the static array is the array address + } + + string srcPath(pathName); + string resolvedPath = CanonicalizeSpecPath(srcPath); + FILE *fp = fopen(resolvedPath.c_str(), "r"); + if (fp == nullptr) { + goto ReadFileFromPath_Finish; + } + byteIO = fread(pDst, 1, readMax, fp); + fclose(fp); + if (byteIO != readMax) { + goto ReadFileFromPath_Finish; + } + ret = 0; + ReadFileFromPath_Finish: + if (ret) { + if (dynamicBuf) { + delete[] pDst; + } + } else { + if (dynamicBuf) { + *buf = pDst; + } + ret = byteIO; + } + return ret; + } + + int WriteBinFile(const char *pathName, const uint8_t *buf, const int bufLen, bool newFile) + { + string mode; + string resolvedPath; + string srcPath(pathName); + if (newFile) { + mode = "wb+"; + // no std::fs supoort, else std::filesystem::canonical,-lstdc++fs + if (srcPath.find("..") != string::npos) { + return ERR_FILE_PATH_CHECK; + } + resolvedPath = srcPath.c_str(); + } else { + mode = "a+"; + resolvedPath = CanonicalizeSpecPath(srcPath); + } + FILE *fp = fopen(resolvedPath.c_str(), mode.c_str()); + if (fp == nullptr) { + WRITE_LOG(LOG_DEBUG, "Write to %s failed!", pathName); + return ERR_FILE_OPEN; + } + int bytesDone = fwrite(buf, 1, bufLen, fp); + fflush(fp); + fclose(fp); + if (bytesDone != bufLen) { + return ERR_BUF_SIZE; + } + return RET_SUCCESS; + } + + void CloseIdleCallback(uv_handle_t *handle) + { + delete (uv_idle_t *)handle; + }; + + void CloseTimerCallback(uv_handle_t *handle) + { + delete (uv_timer_t *)handle; + }; + + // return value: <0 error; 0 can start new server instance; >0 server already exists + int ProgramMutex(const char *procname, bool checkOrNew) + { + char bufPath[BUF_SIZE_DEFAULT] = ""; + char buf[BUF_SIZE_DEFAULT] = ""; + char pidBuf[BUF_SIZE_TINY] = ""; + size_t size = sizeof(buf); + if (uv_os_tmpdir(buf, &size) < 0) { + WRITE_LOG(LOG_FATAL, "Tmppath failed"); + return ERR_API_FAIL; + } + if (snprintf_s(bufPath, sizeof(bufPath), sizeof(bufPath) - 1, "%s%c.%s.pid", buf, Base::GetPathSep(), procname) + < 0) { + return ERR_BUF_OVERFLOW; + } + int pid = static_cast(getpid()); + if (snprintf_s(pidBuf, sizeof(pidBuf), sizeof(pidBuf) - 1, "%d", pid) < 0) { + return ERR_BUF_OVERFLOW; + } + // no need to CanonicalizeSpecPath, else not work + umask(0); + int fd = open(bufPath, O_RDWR | O_CREAT, 0666); // 0666:permission + if (fd < 0) { + WRITE_LOG(LOG_FATAL, "Open mutex file \"%s\" failed!!!Errno:%d\n", buf, errno); + return ERR_FILE_OPEN; + } +#ifdef _WIN32 + if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "Global\\%s", procname) < 0) { + return ERR_BUF_OVERFLOW; + } + HANDLE hMutex = CreateMutex(nullptr, FALSE, buf); + DWORD dwError = GetLastError(); + if (ERROR_ALREADY_EXISTS == dwError || ERROR_ACCESS_DENIED == dwError) { + WRITE_LOG(LOG_DEBUG, "File \"%s\" locked. proc already exit!!!\n", procname); + return 1; + } + if (checkOrNew) { + CloseHandle(hMutex); + } +#else + struct flock fl; + fl.l_type = F_WRLCK; + fl.l_start = 0; + fl.l_whence = SEEK_SET; + fl.l_len = 0; + int retChild = fcntl(fd, F_SETLK, &fl); + if (-1 == retChild) { + WRITE_LOG(LOG_DEBUG, "File \"%s\" locked. proc already exit!!!\n", bufPath); + close(fd); + return 1; + } +#endif + ftruncate(fd, 0); + write(fd, pidBuf, strlen(pidBuf) + 1); + WRITE_LOG(LOG_DEBUG, "Write mutext to %s, pid:%s", bufPath, pidBuf); + if (checkOrNew) { + // close it for check only + close(fd); + } + // Do not close the file descriptor, the process will be mutext effect under no-Win32 OS + return RET_SUCCESS; + } + + void SplitString(const string &origString, const string &seq, vector &resultStrings) + { + string::size_type p1 = 0; + string::size_type p2 = origString.find(seq); + + while (p2 != string::npos) { + if (p2 == p1) { + ++p1; + p2 = origString.find(seq, p1); + continue; + } + resultStrings.push_back(origString.substr(p1, p2 - p1)); + p1 = p2 + seq.size(); + p2 = origString.find(seq, p1); + } + + if (p1 != origString.size()) { + resultStrings.push_back(origString.substr(p1)); + } + } + + string GetShellPath() + { + struct stat filecheck; + string shellPath = "/bin/sh"; + if (stat(shellPath.c_str(), &filecheck) < 0) { + shellPath = "/system/bin/sh"; + if (stat(shellPath.c_str(), &filecheck) < 0) { + shellPath = "sh"; + } + } + return shellPath; + } + + // Not supported on some platforms, Can only be achieved manually + uint64_t HostToNet(uint64_t val) + { + if (htonl(1) == 1) + return val; + return (((uint64_t)htonl(val)) << 32) + htonl(val >> 32); + } + + uint64_t NetToHost(uint64_t val) + { + if (htonl(1) == 1) + return val; + return (((uint64_t)ntohl(val)) << 32) + ntohl(val >> 32); + } + + char GetPathSep() + { +#ifdef _WIN32 + const char sep = '\\'; +#else + const char sep = '/'; +#endif + return sep; + } + + string GetFullFilePath(const string &s) + { // cannot use s.rfind(std::filesystem::path::preferred_separator + size_t i = s.rfind(GetPathSep(), s.length()); + if (i != string::npos) { + return (s.substr(i + 1, s.length() - i)); + } + return s; + } + + int CreateSocketPair(int *fds) + { +#ifndef _WIN32 +#ifdef HOST_MAC + int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); + if (ret == 0) { + for (auto i = 0; i < 2; ++i) { + if (fcntl(fds[i], F_SETFD, FD_CLOEXEC) == -1) { + close(fds[0]); + close(fds[1]); + WRITE_LOG(LOG_WARN, "fcntl failed to set FD_CLOEXEC: %s", strerror(errno)); + return -1; + } + } + } + return ret; +#else + return socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds); +#endif +#else + struct sockaddr_in addr; + socklen_t addrlen = sizeof(addr); + int reuse = 1; + if (fds == 0) { + return -1; + } + int listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listener == -1) { + return -2; + } + Base::ZeroStruct(addr); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = 0; + fds[0] = fds[1] = (int)-1; + do { + if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, (socklen_t)sizeof(reuse))) { + break; + } + if (::bind(listener, (struct sockaddr *)&addr, sizeof(addr))) { + break; + } + if (getsockname(listener, (struct sockaddr *)&addr, &addrlen)) { + break; + } + if (listen(listener, 1)) { + break; + } + fds[0] = socket(AF_INET, SOCK_STREAM, 0); + if (fds[0] == -1) { + break; + } + if (connect(fds[0], (struct sockaddr *)&addr, sizeof(addr)) == -1) { + break; + } + fds[1] = accept(listener, nullptr, nullptr); + if (fds[1] == -1) { + break; + } + closesocket(listener); + return 0; + } while (0); + + closesocket(listener); + closesocket(fds[0]); + closesocket(fds[1]); + return -1; +#endif + } + + void CloseSocketPair(const int *fds) + { +#ifndef _WIN32 + close(fds[0]); + close(fds[1]); +#else + closesocket(fds[0]); + closesocket(fds[1]); +#endif + } + + int StringEndsWith(string s, string sub) + { + return s.rfind(sub) == (s.length() - sub.length()) ? 1 : 0; + } + + // Both absolute and relative paths support + bool CheckDirectoryOrPath(const char *localPath, bool pathOrDir, bool readWrite) + { + if (pathOrDir) { // filepath + uv_fs_t req; + int r = uv_fs_lstat(nullptr, &req, localPath, nullptr); + uv_fs_req_cleanup(&req); + if (r == 0 && req.statbuf.st_mode & S_IFREG) { // is file + uv_fs_access(nullptr, &req, localPath, readWrite ? R_OK : W_OK, nullptr); + uv_fs_req_cleanup(&req); + if (req.result == 0) + return true; + } + } else { // dir + } + return false; + } + + // Using openssl encryption and decryption method, high efficiency; when encrypting more than 64 bytes, + // the carriage return will not be added, and the tail padding 00 is removed when decrypting + // The return value is the length of the string after Base64 + int Base64EncodeBuf(const uint8_t *input, const int length, uint8_t *bufOut) + { + return EVP_EncodeBlock(bufOut, input, length); + } + + vector Base64Encode(const uint8_t *input, const int length) + { + vector retVec; + uint8_t *pBuf = nullptr; + while (true) { + if (static_cast(length) > HDC_BUF_MAX_BYTES) { + break; + } + int base64Size = length * 1.4 + 256; + if (!(pBuf = new uint8_t[base64Size]())) { + break; + } + int childRet = Base64EncodeBuf(input, length, pBuf); + if (childRet <= 0) { + break; + } + retVec.insert(retVec.begin(), pBuf, pBuf + childRet); + break; + } + if (pBuf) { + delete[] pBuf; + } + + return retVec; + } + + inline int CalcDecodeLength(const uint8_t *b64input) + { + int len = strlen(reinterpret_cast(const_cast(b64input))); + if (!len) { + return 0; + } + int padding = 0; + if (b64input[len - 1] == '=' && b64input[len - 2] == '=') { + // last two chars are = + padding = 2; // 2 : last two chars + } else if (b64input[len - 1] == '=') { + // last char is = + padding = 1; + } + return static_cast(len * 0.75 - padding); + } + + // return -1 error; >0 decode size + int Base64DecodeBuf(const uint8_t *input, const int length, uint8_t *bufOut) + { + int nRetLen = CalcDecodeLength(input); + if (!nRetLen) { + return 0; + } + + if (EVP_DecodeBlock(bufOut, input, length) > 0) { + return nRetLen; + } + return 0; + } + + string Base64Decode(const uint8_t *input, const int length) + { + string retString; + uint8_t *pBuf = nullptr; + while (true) { + if ((uint32_t)length > HDC_BUF_MAX_BYTES) { + break; + } + // must less than length + if (!(pBuf = new uint8_t[length]())) { + break; + } + int childRet = Base64DecodeBuf(input, length, pBuf); + if (childRet <= 0) { + break; + } + retString = (reinterpret_cast(pBuf)); + break; + } + if (pBuf) { + delete[] pBuf; + } + return retString; + } + + void ReverseBytes(void *start, int size) + { + uint8_t *istart = (uint8_t *)start; + uint8_t *iend = istart + size; + std::reverse(istart, iend); + } + + // clang-format off + const string StringFormat(const char * const formater, ...) + { + va_list vaArgs; + va_start(vaArgs, formater); + string ret = StringFormat(formater, vaArgs); + va_end(vaArgs); + return ret; + } + + const string StringFormat(const char * const formater, va_list &vaArgs) + { + std::vector args(MAX_SIZE_IOBUF); + const int retSize = vsnprintf_s(args.data(), MAX_SIZE_IOBUF, args.size() - 1, formater, vaArgs); + if (retSize < 0) { + return std::string(""); + } else { + return std::string(args.data(), retSize); + } + } + // clang-format on + + string GetVersion() + { + const uint8_t a = 'a'; + uint8_t major = (HDC_VERSION_NUMBER >> 28) & 0xff; + uint8_t minor = (HDC_VERSION_NUMBER << 4 >> 24) & 0xff; + uint8_t version = (HDC_VERSION_NUMBER << 12 >> 24) & 0xff; + uint8_t fix = (HDC_VERSION_NUMBER << 20 >> 28) & 0xff; // max 16, tail is p + string ver = StringFormat("%x.%x.%x%c", major, minor, version, a + fix); + return "Ver: " + ver; + } + + bool IdleUvTask(uv_loop_t *loop, void *data, uv_idle_cb cb) + { + uv_idle_t *idle = new uv_idle_t(); + if (idle == nullptr) { + return false; + } + idle->data = data; + uv_idle_init(loop, idle); + uv_idle_start(idle, cb); + // delete by callback + return true; + } + + bool TimerUvTask(uv_loop_t *loop, void *data, uv_timer_cb cb, int repeatTimeout) + { + uv_timer_t *timer = new uv_timer_t(); + if (timer == nullptr) { + return false; + } + timer->data = data; + uv_timer_init(loop, timer); + uv_timer_start(timer, cb, 0, repeatTimeout); + // delete by callback + return true; + } + + // callback, uint8_t flag, string msg, const void * data + bool DelayDo(uv_loop_t *loop, const int delayMs, const uint8_t flag, string msg, void *data, + std::function cb) + { + struct DelayDoParam { + uv_timer_t handle; + uint8_t flag; + string msg; + void *data; + std::function cb; + }; + auto funcDelayDo = [](uv_timer_t *handle) -> void { + DelayDoParam *st = (DelayDoParam *)handle->data; + st->cb(st->flag, st->msg, st->data); + uv_close((uv_handle_t *)handle, [](uv_handle_t *handle) { + DelayDoParam *st = (DelayDoParam *)handle->data; + delete st; + }); + }; + DelayDoParam *st = new DelayDoParam(); + if (st == nullptr) { + return false; + } + st->cb = cb; + st->flag = flag; + st->msg = msg; + st->data = data; + st->handle.data = st; + uv_timer_init(loop, &st->handle); + uv_timer_start(&st->handle, funcDelayDo, delayMs, 0); + return true; + } + + string ReplaceAll(string str, const string from, const string to) + { + string::size_type startPos = 0; + while ((startPos = str.find(from, startPos)) != string::npos) { + str.replace(startPos, from.length(), to); + startPos += to.length(); // Handles case where 'to' is a substring of 'from' + } + return str; + } + + string CanonicalizeSpecPath(string &src) + { + char resolvedPath[PATH_MAX] = { 0 }; +#if defined(_WIN32) + if (!_fullpath(resolvedPath, src.c_str(), PATH_MAX)) { + WRITE_LOG(LOG_FATAL, "_fullpath %s failed", src.c_str()); + return ""; + } +#else + if (realpath(src.c_str(), resolvedPath) == nullptr) { + WRITE_LOG(LOG_FATAL, "realpath %s failed", src.c_str()); + return ""; + } +#endif + string res(resolvedPath); + return res; + } + + uint8_t CalcCheckSum(const uint8_t *data, int len) + { + uint8_t ret = 0; + for (int i = 0; i < len; ++i) { + ret += data[i]; + } + return ret; + } + + int open_osfhandle(uv_os_fd_t os_fd) + { + // equal libuv's uv_open_osfhandle, libuv 1.23 added. old libuv not impl... +#ifdef _WIN32 + return _open_osfhandle((intptr_t)os_fd, 0); +#else + return os_fd; +#endif + } + + uv_os_sock_t DuplicateUvSocket(uv_tcp_t *tcp) + { + uv_os_sock_t dupFd = -1; +#ifdef _WIN32 + WSAPROTOCOL_INFO info; + ZeroStruct(info); + if (WSADuplicateSocketA(tcp->socket, GetCurrentProcessId(), &info) < 0) { + return dupFd; + } + dupFd = WSASocketA(0, 0, 0, &info, 0, 0); +#else + uv_os_fd_t fdOs; + if (uv_fileno((const uv_handle_t *)tcp, &fdOs) < 0) { + return ERR_API_FAIL; + } + dupFd = dup(open_osfhandle(fdOs)); +#endif + return dupFd; + } + + vector Md5Sum(uint8_t *buf, int size) + { + vector ret; + uint8_t md5Hash[MD5_DIGEST_LENGTH] = { 0 }; + if (EVP_Digest(buf, size, md5Hash, NULL, EVP_md5(), NULL)) { + ret.insert(ret.begin(), md5Hash, md5Hash + sizeof(md5Hash)); + } + return ret; + } + + string GetCwd() + { + char path[PATH_MAX] = ""; + size_t size = sizeof(path); + string res; + if (uv_cwd(path, &size) < 0) { + return res; + } + if (path[strlen(path) - 1] != Base::GetPathSep()) { + path[strlen(path)] = Base::GetPathSep(); + } + res = path; + return res; + } + + string GetTmpDir() + { + string res; +#ifdef HDC_HOST + char path[PATH_MAX] = ""; + size_t size = sizeof(path); + if (uv_os_tmpdir(path, &size) < 0) { + WRITE_LOG(LOG_FATAL, "get tmppath failed!"); + return res; + } + if (path[strlen(path) - 1] != Base::GetPathSep()) { + path[strlen(path)] = Base::GetPathSep(); + } + res = path; +#else + res = "/data/local/tmp/"; +#endif + return res; + } + + bool IsRoot() + { +#ifdef _WIN32 + // reserve + return true; +#else + if (getuid() == 0) { + return true; + } +#endif + return false; + } + + bool IsAbsolutePath(string &path) + { + bool ret = false; +#ifdef _WIN32 + // shlwapi.h PathIsRelativeA not link in harmony project + // c:\ or UNC path '\\hostname\share\file' + ret = path.find(":\\") == 1 || path.find("\\\\") == 0; +#else + ret = path[0] == '/'; +#endif + return ret; + } +} +} // namespace Hdc diff --git a/services/flashd/common/base.h b/services/flashd/common/base.h new file mode 100755 index 00000000..9a6b12be --- /dev/null +++ b/services/flashd/common/base.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_BASE_H +#define HDC_BASE_H +#include "common.h" + +namespace Hdc { +namespace Base { + void SetLogLevel(const uint8_t logLevel); + void PrintLogEx(const char *functionName, int line, uint8_t logLevel, const char *msg, ...); + void PrintMessage(const char *fmt, ...); + // tcpHandle can't be const as it's passed into uv_tcp_keepalive + void SetTcpOptions(uv_tcp_t *tcpHandle); + // Realloc need to update origBuf&origSize which can't be const + void ReallocBuf(uint8_t **origBuf, int *nOrigSize, const int indexUsedBuf, int sizeWanted); + // handle&sendHandle must keep sync with uv_write + int SendToStreamEx(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen, uv_stream_t *handleSend, + const void *finishCallback, const void *pWriteReqData); + int SendToStream(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen); + // As an uv_write_cb it must keep the same as prototype + void SendCallback(uv_write_t *req, int status); + // As an uv_alloc_cb it must keep the same as prototype + void AllocBufferCallback(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf); + uint64_t GetRuntimeMSec(); + string GetRandomString(const uint16_t expectedLen); + int GetRandomNum(const int min, const int max); + uint64_t GetRandom(const uint64_t min = 0, const uint64_t max = UINT64_MAX); + int ConnectKey2IPPort(const char *connectKey, char *outIP, uint16_t *outPort); + // As an uv_work_cb it must keep the same as prototype + // clang-format off + int StartWorkThread(uv_loop_t *loop, uv_work_cb pFuncWorkThread, + uv_after_work_cb pFuncAfterThread, void *pThreadData); + // clang-format on + // As an uv_work_cb it must keep the same as prototype + void FinishWorkThread(uv_work_t *req, int status); + int GetMaxBufSize(); + bool TryCloseLoop(uv_loop_t *ptrLoop, const char *callerName); + void TryCloseHandle(const uv_handle_t *handle); + void TryCloseHandle(const uv_handle_t *handle, uv_close_cb closeCallBack); + void TryCloseHandle(const uv_handle_t *handle, bool alwaysCallback, uv_close_cb closeCallBack); + char **SplitCommandToArgs(const char *cmdStringLine, int *slotIndex); + bool SetHdcProperty(const char *key, const char *value); + // value needs to save results which can't be const + bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf); + bool RunPipeComand(const char *cmdString, char *outBuf, uint16_t sizeOutBuf, bool ignoreTailLF); + // results need to save in buf which can't be const + int ReadBinFile(const char *pathName, void **buf, const int bufLen); + int WriteBinFile(const char *pathName, const uint8_t *buf, const int bufLen, bool newFile = false); + void CloseIdleCallback(uv_handle_t *handle); + void CloseTimerCallback(uv_handle_t *handle); + int ProgramMutex(const char *procname, bool checkOrNew); + // result needs to save results which can't be const + void SplitString(const string &origString, const string &seq, vector &resultStrings); + string GetShellPath(); + uint64_t HostToNet(uint64_t val); + uint64_t NetToHost(uint64_t val); + string GetFullFilePath(const string &s); + int CreateSocketPair(int *fds); + void CloseSocketPair(const int *fds); + int StringEndsWith(string s, string sub); + bool CheckDirectoryOrPath(const char *localPath, bool pathOrDir, bool readWrite); + int Base64EncodeBuf(const uint8_t *input, const int length, uint8_t *bufOut); + vector Base64Encode(const uint8_t *input, const int length); + int Base64DecodeBuf(const uint8_t *input, const int length, uint8_t *bufOut); + string Base64Decode(const uint8_t *input, const int length); + void ReverseBytes(void *start, int size); + string CanonicalizeSpecPath(string &src); + // Just zero a POD type, such as a structure or union + template int ZeroStruct(T &structBuf) + { + return memset_s(&structBuf, sizeof(T), 0, sizeof(T)); + } + // just zero a statically allocated array of POD or built-in types + template int ZeroArray(T (&arrayBuf)[N]) + { + return memset_s(arrayBuf, sizeof(T) * N, 0, sizeof(T) * N); + } + // just zero memory buf, such as pointer + template int ZeroBuf(T &arrayBuf, int size) + { + return memset_s(arrayBuf, size, 0, size); + } + // clang-format off + const string StringFormat(const char * const formater, ...); + const string StringFormat(const char * const formater, va_list &vaArgs); + // clang-format on + string GetVersion(); + bool IdleUvTask(uv_loop_t *loop, void *data, uv_idle_cb cb); + bool TimerUvTask(uv_loop_t *loop, void *data, uv_timer_cb cb, int repeatTimeout = UV_DEFAULT_INTERVAL); + bool DelayDo(uv_loop_t *loop, const int delayMs, const uint8_t flag, string msg, void *data, + std::function cb); + inline bool DelayDoSimple(uv_loop_t *loop, const int delayMs, + std::function cb) + { + return DelayDo(loop, delayMs, 0, "", nullptr, cb); + } + inline bool DoNextLoop(uv_loop_t *loop, void *data, std::function cb) + { + return DelayDo(loop, 0, 0, "", data, cb); + } + + // Trim from right side + inline string &RightTrim(string &s, const string &w = WHITE_SPACES) + { + s.erase(s.find_last_not_of(w) + 1); + return s; + } + + // Trim from left side + inline string &LeftTrim(string &s, const string &w = WHITE_SPACES) + { + s.erase(0, s.find_first_not_of(w)); + return s; + } + + // Trim from both sides + inline string &Trim(string &s, const string &w = WHITE_SPACES) + { + return LeftTrim(RightTrim(s, w), w); + } + string ReplaceAll(string str, const string from, const string to); + uint8_t CalcCheckSum(const uint8_t *data, int len); + string GetFileNameAny(string &path); + string GetCwd(); + string GetTmpDir(); + uv_os_sock_t DuplicateUvSocket(uv_tcp_t *tcp); + vector Md5Sum(uint8_t *buf, int size); + bool IsRoot(); + char GetPathSep(); + bool IsAbsolutePath(string &path); +} // namespace base +} // namespace Hdc + +#endif // HDC_BASE_H \ No newline at end of file diff --git a/services/flashd/common/channel.cpp b/services/flashd/common/channel.cpp new file mode 100755 index 00000000..8d944ac5 --- /dev/null +++ b/services/flashd/common/channel.cpp @@ -0,0 +1,434 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "channel.h" +namespace Hdc { +HdcChannelBase::HdcChannelBase(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn) +{ + SetChannelTCPString(addrString); + isServerOrClient = serverOrClient; + loopMain = loopMainIn; + uv_rwlock_init(&mainAsync); + uv_async_init(loopMain, &asyncMainLoop, MainAsyncCallback); + uv_rwlock_init(&lockMapChannel); +} + +HdcChannelBase::~HdcChannelBase() +{ + ClearChannels(); + // clear + if (!uv_is_closing((uv_handle_t *)&asyncMainLoop)) { + uv_close((uv_handle_t *)&asyncMainLoop, nullptr); + } + + uv_rwlock_destroy(&mainAsync); + uv_rwlock_destroy(&lockMapChannel); +} + +vector HdcChannelBase::GetChannelHandshake(string &connectKey) const +{ + vector ret; + // clang-format off + struct ChannelHandShake handshake = {{0}}; + // clang-format on + Base::ZeroStruct(handshake); + if (strcpy_s(handshake.banner, sizeof(handshake.banner), HANDSHAKE_MESSAGE.c_str()) != EOK) { + return ret; + } + if (strcpy_s(handshake.connectKey, sizeof(handshake.connectKey), connectKey.c_str()) != EOK) { + return ret; + } + ret.insert(ret.begin(), (uint8_t *)&handshake, (uint8_t *)&handshake + sizeof(ChannelHandShake)); + return ret; +} + +bool HdcChannelBase::SetChannelTCPString(const string &addrString) +{ + bool ret = false; + while (true) { + if (addrString.find(":") == string::npos) { + break; + } + string host = addrString.substr(0, addrString.find(":")); + string port = addrString.substr(addrString.find(":") + 1); + channelPort = std::atoi(port.c_str()); + sockaddr_in addr; + if (!channelPort || uv_ip4_addr(host.c_str(), channelPort, &addr) != 0) { + break; + } + channelHost = host; + channelHostPort = addrString; + ret = true; + break; + } + if (!ret) { + channelPort = 0; + channelHost = STRING_EMPTY; + channelHostPort = STRING_EMPTY; + } + return ret; +} + +void HdcChannelBase::ClearChannels() +{ + for (auto v : mapChannel) { + HChannel hChannel = (HChannel)v.second; + if (!hChannel->isDead) { + FreeChannel(hChannel->channelId); + } + } +} + +void HdcChannelBase::WorkerPendding() +{ + WRITE_LOG(LOG_DEBUG, "Begin host channel pendding"); + uv_run(loopMain, UV_RUN_DEFAULT); + uv_loop_close(loopMain); +} + +void HdcChannelBase::ReadStream(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf) +{ + int size = 0; + int indexBuf = 0; + int childRet = 0; + bool needExit = false; + HChannel hChannel = (HChannel)tcp->data; + HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; + + if (nread == UV_ENOBUFS) { + WRITE_LOG(LOG_DEBUG, "HdcChannelBase::ReadStream Pipe IOBuf max"); + return; + } else if (nread == 0) { + // maybe just afer accept, second client req + WRITE_LOG(LOG_DEBUG, "HdcChannelBase::ReadStream idle read"); + return; + } else if (nread < 0) { + Base::TryCloseHandle((uv_handle_t *)tcp); + WRITE_LOG(LOG_DEBUG, "HdcChannelBase::ReadStream failed2:%s", uv_err_name(nread)); + needExit = true; + goto Finish; + } else { + hChannel->availTailIndex += nread; + } + while (hChannel->availTailIndex > DWORD_SERIALIZE_SIZE) { + size = ntohl(*(uint32_t *)(hChannel->ioBuf + indexBuf)); // big endian + if (size <= 0 || (uint32_t)size > HDC_BUF_MAX_BYTES) { + needExit = true; + break; + } + if (hChannel->availTailIndex - DWORD_SERIALIZE_SIZE < size) { + break; + } + childRet = thisClass->ReadChannel(hChannel, (uint8_t *)hChannel->ioBuf + DWORD_SERIALIZE_SIZE + indexBuf, size); + if (childRet < 0) { + if (!hChannel->keepAlive) { + needExit = true; + break; + } + } + // update io + hChannel->availTailIndex -= (DWORD_SERIALIZE_SIZE + size); + indexBuf += DWORD_SERIALIZE_SIZE + size; + } + if (indexBuf > 0 && hChannel->availTailIndex > 0) { + if (memmove_s(hChannel->ioBuf, hChannel->bufSize, hChannel->ioBuf + indexBuf, hChannel->availTailIndex)) { + needExit = true; + goto Finish; + } + } + +Finish: + if (needExit) { + thisClass->FreeChannel(hChannel->channelId); + WRITE_LOG(LOG_DEBUG, "Read Stream needExit, FreeChannel finish"); + } +} + +void HdcChannelBase::WriteCallback(uv_write_t *req, int status) +{ + HChannel hChannel = (HChannel)req->handle->data; + --hChannel->sendRef; + HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; + if (status < 0) { + Base::TryCloseHandle((uv_handle_t *)req->handle); + if (!hChannel->isDead && !hChannel->sendRef) { + thisClass->FreeChannel(hChannel->channelId); + WRITE_LOG(LOG_DEBUG, "WriteCallback TryCloseHandle"); + } + } + delete[]((uint8_t *)req->data); + delete req; +} + +void HdcChannelBase::AsyncMainLoopTask(uv_idle_t *handle) +{ + AsyncParam *param = (AsyncParam *)handle->data; + HdcChannelBase *thisClass = (HdcChannelBase *)param->thisClass; + + switch (param->method) { + case ASYNC_FREE_SESSION: { + // alloc/release should pair in main thread. + thisClass->FreeChannel(param->sid); + break; + } + default: + break; + } + if (param->data) { + delete[]((uint8_t *)param->data); + } + delete param; + uv_close((uv_handle_t *)handle, Base::CloseIdleCallback); +} + +// multiple uv_async_send() calls may be merged by libuv,so not each call will yield callback as expected. +// eg: if uv_async_send() 5 times before callback calling,it will be called only once. +// if uv_async_send() is called again after callback calling, it will be called again. +void HdcChannelBase::MainAsyncCallback(uv_async_t *handle) +{ + HdcChannelBase *thisClass = (HdcChannelBase *)handle->data; + if (uv_is_closing((uv_handle_t *)thisClass->loopMain)) { + return; + } + list::iterator i; + list &lst = thisClass->lstMainThreadOP; + uv_rwlock_wrlock(&thisClass->mainAsync); + for (i = lst.begin(); i != lst.end();) { + AsyncParam *param = (AsyncParam *)*i; + Base::IdleUvTask(thisClass->loopMain, param, AsyncMainLoopTask); + i = lst.erase(i); + } + uv_rwlock_wrunlock(&thisClass->mainAsync); +} + +void HdcChannelBase::PushAsyncMessage(const uint32_t channelId, const uint8_t method, const void *data, + const int dataSize) +{ + if (uv_is_closing((uv_handle_t *)&asyncMainLoop)) { + return; + } + auto param = new AsyncParam(); + if (!param) { + return; + } + param->sid = channelId; // Borrow SID storage + param->thisClass = this; + param->method = method; + if (dataSize > 0) { + param->dataSize = dataSize; + param->data = new uint8_t[param->dataSize](); + if (!param->data) { + delete param; + return; + } + if (memcpy_s((uint8_t *)param->data, param->dataSize, data, dataSize)) { + delete[]((uint8_t *)param->data); + delete param; + return; + } + } + asyncMainLoop.data = this; + uv_rwlock_wrlock(&mainAsync); + lstMainThreadOP.push_back(param); + uv_rwlock_wrunlock(&mainAsync); + uv_async_send(&asyncMainLoop); +} + +// client to server, or vice versa +// works only in current working thread +void HdcChannelBase::Send(const uint32_t channelId, uint8_t *bufPtr, const int size) +{ + uv_stream_t *sendStream = nullptr; + int sizeNewBuf = size + DWORD_SERIALIZE_SIZE; + HChannel hChannel = (HChannel)AdminChannel(OP_QUERY, channelId, nullptr); + if (!hChannel || hChannel->isDead) { + return; + } + auto data = new uint8_t[sizeNewBuf](); + if (!data) { + return; + } + *(uint32_t *)data = htonl(size); // big endian + if (memcpy_s(data + DWORD_SERIALIZE_SIZE, sizeNewBuf - DWORD_SERIALIZE_SIZE, bufPtr, size)) { + delete[] data; + return; + } + if (hChannel->hWorkThread == uv_thread_self()) { + sendStream = (uv_stream_t *)&hChannel->hWorkTCP; + } else { + sendStream = (uv_stream_t *)&hChannel->hChildWorkTCP; + } + if (!uv_is_closing((const uv_handle_t *)sendStream) && uv_is_writable(sendStream)) { + ++hChannel->sendRef; + Base::SendToStreamEx(sendStream, data, sizeNewBuf, nullptr, (void *)WriteCallback, data); + } +} + +void HdcChannelBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) +{ + if (sizeWanted <= 0) { + return; + } + HChannel context = (HChannel)handle->data; + Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); + buf->base = (char *)context->ioBuf + context->availTailIndex; + buf->len = context->bufSize - context->availTailIndex - 1; + if (buf->len < 0) { + buf->len = 0; + } +} + +uint32_t HdcChannelBase::MallocChannel(HChannel *hOutChannel) +{ + auto hChannel = new HdcChannel(); + if (!hChannel) { + return 0; + } + uint32_t channelId = Base::GetRuntimeMSec(); + if (isServerOrClient) { + hChannel->serverOrClient = isServerOrClient; + ++channelId; // Use different value for serverForClient&client in per process + } + uv_tcp_init(loopMain, &hChannel->hWorkTCP); + ++hChannel->uvRef; + hChannel->hWorkThread = uv_thread_self(); + hChannel->hWorkTCP.data = hChannel; + hChannel->clsChannel = this; + hChannel->channelId = channelId; + AdminChannel(OP_ADD, channelId, hChannel); + *hOutChannel = hChannel; + WRITE_LOG(LOG_DEBUG, "Mallocchannel:%d", channelId); + return channelId; +} + +// work when libuv-handle at struct of HdcSession has all callback finished +void HdcChannelBase::FreeChannelFinally(uv_idle_t *handle) +{ + HChannel hChannel = (HChannel)handle->data; + HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; + if (hChannel->uvRef > 0) { + return; + } + thisClass->NotifyInstanceChannelFree(hChannel); + thisClass->AdminChannel(OP_REMOVE, hChannel->channelId, nullptr); + WRITE_LOG(LOG_DEBUG, "!!!FreeChannelFinally channelId:%d finish", hChannel->channelId); + if (!hChannel->serverOrClient) { + uv_stop(thisClass->loopMain); + } + delete hChannel; + Base::TryCloseHandle((const uv_handle_t *)handle, Base::CloseIdleCallback); +} + +void HdcChannelBase::FreeChannelContinue(HChannel hChannel) +{ + auto closeChannelHandle = [](uv_handle_t *handle) -> void { + HChannel hChannel = (HChannel)handle->data; + --hChannel->uvRef; + Base::TryCloseHandle((uv_handle_t *)handle); + }; + hChannel->availTailIndex = 0; + if (hChannel->ioBuf) { + delete[] hChannel->ioBuf; + hChannel->ioBuf = nullptr; + } + if (!hChannel->serverOrClient) { + Base::TryCloseHandle((uv_handle_t *)&hChannel->stdinTty, closeChannelHandle); + Base::TryCloseHandle((uv_handle_t *)&hChannel->stdoutTty, closeChannelHandle); + } + if (uv_is_closing((const uv_handle_t *)&hChannel->hWorkTCP)) { + --hChannel->uvRef; + } else { + Base::TryCloseHandle((uv_handle_t *)&hChannel->hWorkTCP, closeChannelHandle); + } + Base::IdleUvTask(loopMain, hChannel, FreeChannelFinally); +} + +void HdcChannelBase::FreeChannelOpeate(uv_timer_t *handle) +{ + HChannel hChannel = (HChannel)handle->data; + HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; + if (hChannel->sendRef > 0) { + return; + } + if (hChannel->hChildWorkTCP.loop) { + auto ctrl = HdcSessionBase::BuildCtrlString(SP_DEATCH_CHANNEL, hChannel->channelId, nullptr, 0); + thisClass->ChannelSendSessionCtrlMsg(ctrl, hChannel->targetSessionId); + auto callbackCheckFreeChannelContinue = [](uv_timer_t *handle) -> void { + HChannel hChannel = (HChannel)handle->data; + HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; + if (!hChannel->childCleared) { + return; + } + Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseTimerCallback); + thisClass->FreeChannelContinue(hChannel); + }; + Base::TimerUvTask(thisClass->loopMain, hChannel, callbackCheckFreeChannelContinue); + } else { + thisClass->FreeChannelContinue(hChannel); + } + Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseTimerCallback); +} + +void HdcChannelBase::FreeChannel(const uint32_t channelId) +{ + HChannel hChannel = AdminChannel(OP_QUERY, channelId, nullptr); + if (!hChannel) { + return; + } + // Two cases: alloc in main thread, or work thread + if (hChannel->hWorkThread != uv_thread_self()) { + PushAsyncMessage(hChannel->channelId, ASYNC_FREE_SESSION, nullptr, 0); + return; + } + if (hChannel->isDead) { + return; + } + Base::TimerUvTask(loopMain, hChannel, FreeChannelOpeate, MINOR_TIMEOUT); // do immediately + hChannel->isDead = true; +} + +HChannel HdcChannelBase::AdminChannel(const uint8_t op, const uint32_t channelId, HChannel hInput) +{ + HChannel hRet = nullptr; + switch (op) { + case OP_ADD: + uv_rwlock_wrlock(&lockMapChannel); + mapChannel[channelId] = hInput; + uv_rwlock_wrunlock(&lockMapChannel); + break; + case OP_REMOVE: + uv_rwlock_wrlock(&lockMapChannel); + mapChannel.erase(channelId); + uv_rwlock_wrunlock(&lockMapChannel); + break; + case OP_QUERY: + uv_rwlock_rdlock(&lockMapChannel); + if (mapChannel.count(channelId)) { + hRet = mapChannel[channelId]; + } + uv_rwlock_rdunlock(&lockMapChannel); + break; + case OP_UPDATE: + uv_rwlock_wrlock(&lockMapChannel); + // remove old + mapChannel.erase(channelId); + mapChannel[hInput->channelId] = hInput; + uv_rwlock_wrunlock(&lockMapChannel); + break; + default: + break; + } + return hRet; +} +} \ No newline at end of file diff --git a/services/flashd/common/channel.h b/services/flashd/common/channel.h new file mode 100755 index 00000000..72b81813 --- /dev/null +++ b/services/flashd/common/channel.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_CHANNEL_H +#define HDC_CHANNEL_H +#include "common.h" + +namespace Hdc { +class HdcChannelBase { +public: + HdcChannelBase(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn); + virtual ~HdcChannelBase(); + HChannel AdminChannel(const uint8_t op, const uint32_t channelId, HChannel hInput); + static void AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf); + static void ReadStream(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf); + void PushAsyncMessage(const uint32_t channelId, const uint8_t method, const void *data, const int dataSize); + void WorkerPendding(); + void FreeChannel(const uint32_t channelId); + vector GetChannelHandshake(string &connectKey) const; + +protected: + struct ChannelHandShake { + char banner[12]; // must first index + union { + uint32_t channelId; + char connectKey[MAX_CONNECTKEY_SIZE]; + }; + } __attribute__((packed)); + uint32_t MallocChannel(HChannel *hOutChannel); + virtual int ReadChannel(HChannel hChannel, uint8_t *bufPtr, const int bytesIO) + { + return 0; + } + virtual void NotifyInstanceChannelFree(HChannel hChannel) {}; + void Send(const uint32_t channelId, uint8_t *bufPtr, const int size); + virtual bool ChannelSendSessionCtrlMsg(vector &ctrlMsg, uint32_t sessionId) + { + return true; // just server use + } + + string channelHostPort; + string channelHost; + uint16_t channelPort; + uv_loop_t *loopMain; + bool isServerOrClient; + uv_rwlock_t mainAsync; + uv_async_t asyncMainLoop; + list lstMainThreadOP; + +private: + static void MainAsyncCallback(uv_async_t *handle); + static void WriteCallback(uv_write_t *req, int status); + static void AsyncMainLoopTask(uv_idle_t *handle); + static void FreeChannelOpeate(uv_timer_t *handle); + static void FreeChannelFinally(uv_idle_t *handle); + void ClearChannels(); + void FreeChannelContinue(HChannel hChannel); + bool SetChannelTCPString(const string &addrString); + + uv_rwlock_t lockMapChannel; // protect mapChannel + map mapChannel; +}; +} // namespace Hdc + +#endif // HDC_CHANNEL_H \ No newline at end of file diff --git a/services/flashd/common/common.h b/services/flashd/common/common.h new file mode 100755 index 00000000..e90125ba --- /dev/null +++ b/services/flashd/common/common.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_COMMON_H +#define HDC_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using std::condition_variable; +using std::list; +using std::map; +using std::mutex; +using std::string; +using std::vector; + +// clang-format off +#include // libuv 1.35 +#ifdef HDC_HOST + +#ifdef HARMONY_PROJECT +#include +#else // NOT HARMONY_PROJECT +#include +#endif // END HARMONY_PROJECT + +#else // NOT HDC_HOST +#endif // HDC_HOST + +#ifndef _WIN32 +#include +#include +#endif + +#include + +#include "define.h" +#include "debug.h" +#include "base.h" +#include "task.h" +#include "channel.h" +#include "session.h" +#include "auth.h" + +#include "tcp.h" +#include "usb.h" +#include "file_descriptor.h" + +// clang-format on + +#endif // !defined(COMMON_H_INCLUDED) diff --git a/services/flashd/common/debug.cpp b/services/flashd/common/debug.cpp new file mode 100755 index 00000000..30b81c7e --- /dev/null +++ b/services/flashd/common/debug.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "debug.h" +#include "base.h" + +namespace Hdc { +namespace Debug { + int WriteHexToDebugFile(const char *fileName, const uint8_t *buf, const int bufLen) + { + char pathName[BUF_SIZE_DEFAULT]; + if (snprintf_s(pathName, sizeof(pathName), sizeof(pathName) - 1, "/mnt/hgfs/vtmp/%s", fileName) < 0) { + return ERR_BUF_OVERFLOW; + } + string srcPath = pathName; + string resolvedPath = Base::CanonicalizeSpecPath(srcPath); + FILE *fp = fopen(resolvedPath.c_str(), "a+"); + if (fp == nullptr) { + if (snprintf_s(pathName, sizeof(pathName), sizeof(pathName) - 1, "/tmp/%s", fileName) < 0) { + WRITE_LOG(LOG_DEBUG, "Write hex to %s failed!", pathName); + return ERR_FILE_OPEN; + } + + srcPath = pathName; + resolvedPath = Base::CanonicalizeSpecPath(srcPath); + if ((fp = fopen(resolvedPath.c_str(), "a+")) == nullptr) { + WRITE_LOG(LOG_DEBUG, "Write hex to %s failed!", pathName); + return ERR_FILE_OPEN; + } + } + fwrite(buf, 1, bufLen, fp); + fflush(fp); + fclose(fp); + return RET_SUCCESS; + } + + int ReadHexFromDebugFile(const char *fileName, uint8_t *buf, const int bufLen) + { + char pathName[BUF_SIZE_DEFAULT]; + if (snprintf_s(pathName, sizeof(pathName), sizeof(pathName) - 1, "/mnt/hgfs/vtmp/%s", fileName) < 0) { + return ERR_BUF_OVERFLOW; + } + FILE *fp = fopen(pathName, "r"); + if (fp == nullptr) { + if (snprintf_s(pathName, sizeof(pathName), sizeof(pathName) - 1, "/tmp/%s", fileName) < 0 + || (fp = fopen(pathName, "r")) == nullptr) { + if (fp != nullptr) { + fclose(fp); + } + WRITE_LOG(LOG_DEBUG, "Write hex to %s failed!", pathName); + return ERR_FILE_WRITE; + } + } + struct stat statbuf; + stat(pathName, &statbuf); + int size = statbuf.st_size; + if (size > bufLen) { + fclose(fp); + return ERR_BUF_SIZE; + } + int ret = fread(buf, 1, size, fp); + fflush(fp); + fclose(fp); + if (ret != size) { + return ERR_FILE_READ; + } + return size; + } + + void DetermineThread(HSession hSession) + { + if (uv_thread_self() == hSession->hWorkThread) { + WRITE_LOG(LOG_WARN, "At main workthread"); + } else if (uv_thread_self() == hSession->hWorkChildThread) { + WRITE_LOG(LOG_WARN, "At child workthread"); + } else { + WRITE_LOG(LOG_WARN, "At unknow workthread"); + } + } + + int PrintfHexBuf(const uint8_t *buf, int bufLen) + { + int i = 0; + for (i = 0; i < bufLen; ++i) { + printf("0x%02x, ", buf[i]); + fflush(stdout); + } + printf("\r\n"); + fflush(stdout); + return 0; + } +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/debug.h b/services/flashd/common/debug.h new file mode 100755 index 00000000..b14d1e10 --- /dev/null +++ b/services/flashd/common/debug.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DEBUG_H +#define HDC_DEBUG_H +#include "common.h" + +namespace Hdc { +namespace Debug { + int WriteHexToDebugFile(const char *fileName, const uint8_t *buf, const int bufLen); + int ReadHexFromDebugFile(const char *fileName, uint8_t *buf, const int bufLen); + void DetermineThread(HSession hSession); + int PrintfHexBuf(const uint8_t *buf, int bufLen); +} +} // namespace Hdc + +#endif \ No newline at end of file diff --git a/services/flashd/common/define.h b/services/flashd/common/define.h new file mode 100755 index 00000000..0c1ddf0d --- /dev/null +++ b/services/flashd/common/define.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DEFINE_H +#define HDC_DEFINE_H +#include "define_plus.h" + +namespace Hdc { +// ############################## config ####################################### +constexpr uint8_t MINOR_TIMEOUT = 5; +constexpr uint8_t SIZE_THREAD_POOL = 16; +constexpr uint8_t GLOBAL_TIMEOUT = 30; +constexpr uint16_t DEFAULT_PORT = 8710; +constexpr uint16_t MAX_SIZE_IOBUF = 5120; // USB EP block max size about 10k, USBFFS_BULKSIZE 16384 +constexpr bool ENABLE_IO_CHECKSUM = false; +const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; + +// ################################ macro define ################################### +constexpr uint8_t DWORD_SERIALIZE_SIZE = 4; +constexpr uint8_t CMD_ARG1_COUNT = 2; +constexpr uint8_t STREAM_MAIN = 0; // work at main thread +constexpr uint8_t STREAM_WORK = 1; // work at work thread +constexpr uint16_t BUF_SIZE_MICRO = 16; +constexpr uint16_t BUF_SIZE_TINY = 64; +constexpr uint16_t BUF_SIZE_SMALL = 256; +constexpr uint16_t BUF_SIZE_MEDIUM = 512; +constexpr uint16_t BUF_SIZE_DEFAULT = 1024; +constexpr uint16_t BUF_SIZE_DEFAULT2 = BUF_SIZE_DEFAULT * 2; +constexpr uint16_t BUF_SIZE_DEFAULT4 = BUF_SIZE_DEFAULT * 4; +constexpr uint16_t MAX_IP_PORT = 65535; +constexpr uint16_t MAX_CONNECTKEY_SIZE = 32; // usb sn/tcp ipport +constexpr uint16_t TIME_BASE = 1000; // time unit conversion base value +constexpr uint16_t AID_SHELL = 2000; +constexpr uint16_t UV_DEFAULT_INTERVAL = 250; // ms +constexpr uint16_t VER_PROTOCOL = 0x01; +constexpr uint16_t EXTRA_ALLOC_SIZE = 2048; +// double-word(hex)=[0]major[1][2]minor[3][4]version[5]fix(a-p)[6][7]reserve +constexpr uint32_t HDC_VERSION_NUMBER = 0x10101800; // 1.1.1b=0x10101100 +constexpr uint32_t HDC_BUF_MAX_BYTES = 1024000000; + +const string WHITE_SPACES = " \t\n\r"; +const string UT_TMP_PATH = "/tmp/hdc-ut"; +const string LOG_FILE_NAME = "hdc.log"; +const string SERVER_NAME = "HDCServer"; +const string STRING_EMPTY = ""; +const string HANDSHAKE_MESSAGE = "OHOS HDC"; // sep not char '-', not more than 11 bytes +const string PACKET_FLAG = "HW"; // must 2bytes +const string EMPTY_ECHO = "[Empty]"; +const string MESSAGE_INFO = "[Info]"; +const string MESSAGE_FAIL = "[Fail]"; +const string MESSAGE_SUCCESS = "[Success]"; +// input command +const string CMDSTR_SOFTWARE_VERSION = "version"; +const string CMDSTR_SOFTWARE_HELP = "help"; +const string CMDSTR_TARGET_DISCOVER = "discover"; +const string CMDSTR_SERVICE_START = "start"; +const string CMDSTR_SERVICE_KILL = "kill"; +const string CMDSTR_GENERATE_KEY = "keygen"; +const string CMDSTR_KILL_SERVER = "kserver"; +const string CMDSTR_KILL_DAEMON = "kdaemon"; +const string CMDSTR_LIST_TARGETS = "list targets"; +const string CMDSTR_CONNECT_TARGET = "tconn"; +const string CMDSTR_CONNECT_ANY = "any"; +const string CMDSTR_SHELL = "shell"; +const string CMDSTR_TARGET_REBOOT = "target boot"; +const string CMDSTR_TARGET_MOUNT = "target mount"; +const string CMDSTR_STARTUP_MODE = "smode"; +const string CMDSTR_TARGET_MODE = "tmode"; +const string CMDSTR_BUGREPORT = "bugreport"; +const string CMDSTR_HILOG = "hilog"; +const string CMDSTR_TMODE_USB = "usb"; +const string CMDSTR_TMODE_TCP = "tcp"; +const string CMDSTR_FILE_SEND = "file send"; +const string CMDSTR_FILE_RECV = "file recv"; +const string CMDSTR_FORWARD_FPORT = "fport"; +const string CMDSTR_FORWARD_RPORT = "rport"; +const string CMDSTR_APP_INSTALL = "install"; +const string CMDSTR_APP_UNINSTALL = "uninstall"; +const string CMDSTR_APP_SIDELOAD = "sideload"; +const string CMDSTR_LIST_JDWP = "jpid"; +const string CMDSTR_UPDATE_SYSTEM = "update"; +const string CMDSTR_FLASH_PARTITION = "flash"; +const string CMDSTR_ERASE_PARTITION = "erase"; +const string CMDSTR_FORMAT_PARTITION = "format"; +const string CMDSTR_INNER_ENABLE_KEEPALIVE = "alive"; +} // namespace Hdc +#endif // HDC_DEFINE_H diff --git a/services/flashd/common/define_plus.h b/services/flashd/common/define_plus.h new file mode 100755 index 00000000..0e4c22b7 --- /dev/null +++ b/services/flashd/common/define_plus.h @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef DEFINE_PLUS_H +#define DEFINE_PLUS_H + +namespace Hdc { +constexpr uint8_t LOG_LEVEL_FULL = 5; +// ############################# enum define ################################### +enum LogLevel { + LOG_OFF, + LOG_FATAL, + LOG_INFO, // default + LOG_WARN, + LOG_DEBUG, + LOG_FULL, + LOG_LAST = LOG_FULL, // tail, not use +}; +#define WRITE_LOG(x, y...) Base::PrintLogEx(__FILE__, __LINE__, x, y) + +enum MessageLevel { + MSG_FAIL, + MSG_INFO, + MSG_OK, +}; + +enum ConnType { CONN_USB = 0, CONN_TCP, CONN_SERIAL, CONN_BT }; +enum ConnStatus { STATUS_UNKNOW = 0, STATUS_READY, STATUS_CONNECTED, STATUS_OFFLINE }; + +enum OperateID { + OP_ADD, + OP_REMOVE, + OP_QUERY, + OP_GET_STRLIST, + OP_GET_STRLIST_FULL, + OP_GET_ANY, + OP_UPDATE, + OP_CLEAR, + OP_INIT, + OP_GET_ONLY +}; + +enum RetErrCode { + RET_SUCCESS = 0, + ERR_GENERIC = -1, + ERR_BUF_SIZE = -10000, + ERR_BUF_ALLOC, + ERR_BUF_OVERFLOW, + ERR_BUF_CHECK, + ERR_BUF_RESET, + ERR_BUF_COPY, + ERR_FILE_OPEN = -11000, + ERR_FILE_READ, + ERR_FILE_WRITE, + ERR_FILE_STAT, + ERR_FILE_PATH_CHECK, + ERR_PARM_FORMAT = -12000, + ERR_PARM_SIZE, + ERR_PARM_FAIL, + ERR_API_FAIL = -13000, + ERR_IO_FAIL = -14000, + ERR_IO_TIMEOUT, + ERR_IO_SOFT_RESET, + ERR_SESSION_NOFOUND = -15000, + ERR_SESSION_OFFLINE, + ERR_SESSION_DEAD, + ERR_HANDSHAKE_NOTMATCH = -16000, + ERR_HANDSHAKE_CONNECTKEY_FAILED, + ERR_HANDSHAKE_HANGUP_CHILD, + ERR_SOCKET_FAIL = -17000, + ERR_SOCKET_DUPLICATE, + ERR_MODULE_JDWP_FAILED = -18000, + ERR_UT_MODULE_NOTREADY = -19000, + ERR_UT_MODULE_WAITMAX, + ERR_THREAD_MUTEX_FAIL = -20000, + ERR_PROCESS_SUB_FAIL = -21000, + ERR_PRIVELEGE_NEED = -22000, +}; + +// Flags shared by multiple modules +enum AsyncEvent { + ASYNC_STOP_MAINLOOP = 0, + ASYNC_FREE_SESSION, +}; +enum InnerCtrlCommand { + SP_START_SESSION = 0, + SP_STOP_SESSION, + SP_ATTACH_CHANNEL, + SP_DEATCH_CHANNEL, + SP_JDWP_NEWFD, +}; + +enum HdcCommand { + // core commands types + CMD_KERNEL_HELP = 0, + CMD_KERNEL_HANDSHAKE, + CMD_KERNEL_CHANNEL_CLOSE, + CMD_KERNEL_SERVER_KILL, + CMD_KERNEL_TARGET_DISCOVER, + CMD_KERNEL_TARGET_LIST, + CMD_KERNEL_TARGET_ANY, + CMD_KERNEL_TARGET_CONNECT, + CMD_KERNEL_TARGET_DISCONNECT, + CMD_KERNEL_ECHO, + CMD_KERNEL_ECHO_RAW, + CMD_KERNEL_ENABLE_KEEPALIVE, + // One-pass simple commands + CMD_UNITY_EXECUTE = 1000, + CMD_UNITY_REMOUNT, + CMD_UNITY_REBOOT, + CMD_UNITY_RUNMODE, + CMD_UNITY_HILOG, + CMD_UNITY_TERMINATE, + CMD_UNITY_ROOTRUN, + CMD_UNITY_BUGREPORT_INIT, + CMD_UNITY_BUGREPORT_DATA, + CMD_UNITY_JPID, + // Shell commands types + CMD_SHELL_INIT = 2000, + CMD_SHELL_DATA, + // Forward commands types + CMD_FORWARD_INIT = 2500, + CMD_FORWARD_CHECK, + CMD_FORWARD_CHECK_RESULT, + CMD_FORWARD_ACTIVE_SLAVE, + CMD_FORWARD_ACTIVE_MASTER, + CMD_FORWARD_DATA, + CMD_FORWARD_FREE_CONTEXT, + CMD_FORWARD_LIST, + CMD_FORWARD_REMOVE, + CMD_FORWARD_SUCCESS, + // File commands + CMD_FILE_INIT = 3000, + CMD_FILE_CHECK, + CMD_FILE_BEGIN, + CMD_FILE_DATA, + CMD_FILE_FINISH, + CMD_APP_SIDELOAD, + // App commands + CMD_APP_INIT = 3500, + CMD_APP_CHECK, + CMD_APP_BEGIN, + CMD_APP_DATA, + CMD_APP_FINISH, + CMD_APP_UNINSTALL, + // update + CMD_UPDATER_UPDATE_INIT = 4000, + CMD_UPDATER_FLASH_INIT, + CMD_UPDATER_CHECK, + CMD_UPDATER_BEGIN, + CMD_UPDATER_DATA, + CMD_UPDATER_FINISH = 4005, + CMD_UPDATER_ERASE, + CMD_UPDATER_FORMAT, + CMD_UPDATER_PROGRESS +}; + +enum UsbProtocolOption { + USB_OPTION_TAIL = 1, + USB_OPTION_RESET = 2, + USB_OPTION_RESERVE4 = 4, + USB_OPTION_RESERVE8 = 8, + USB_OPTION_RESERVE16 = 16, +}; +// ################################### struct define ################################### +#pragma pack(push) +#pragma pack(1) + +struct USBHead { + uint8_t flag[2]; + uint8_t option; + uint32_t sessionId; + uint16_t dataSize; +}; + +struct AsyncParam { + void *context; // context=hsession or hchannel + uint32_t sid; // sessionId/channelId + void *thisClass; // caller's class ptr + uint16_t method; + int dataSize; + void *data; // put it in the last +}; + +struct TaskInformation { + uint8_t taskType; + uint32_t sessionId; + uint32_t channelId; + bool hasInitial; + bool taskStop; + bool taskFree; + bool serverOrDaemon; + uv_loop_t *runLoop; + void *taskClass; + void *ownerSessionClass; +}; +using HTaskInfo = TaskInformation *; + +#pragma pack(pop) + +struct HdcUSB { +#ifdef HDC_HOST + libusb_context *ctxUSB = nullptr; // child-use, main null + libusb_device *device; + libusb_device_handle *devHandle; + uint8_t interfaceNumber; + uint16_t retryCount; + // D2H device to host endpoint's address + uint8_t epDevice; + // H2D host to device endpoint's address + uint8_t epHost; + uint8_t devId; + uint8_t busId; + int32_t sizeEpBuf; + uint16_t wMaxPacketSize; + string serialNumber; + string usbMountPoint; + uint8_t *bufDevice; + uint8_t *bufHost; + + mutex lockDeviceHandle; + libusb_transfer *transferRecv; + bool recvIOComplete; + + mutex lockSend; + condition_variable cvTransferSend; + libusb_transfer *transferSend; + bool sendIOComplete; +#else + // usb accessory FunctionFS + // USB main thread use, sub-thread disable, sub-thread uses the main thread USB handle + int bulkOut; // EP1 device recv + int bulkIn; // EP2 device send +#endif + vector bufRecv; + bool resetIO; // if true, must break write and read,default false +}; +using HUSB = struct HdcUSB *; + +struct HdcSession { + bool serverOrDaemon; // instance of daemon or server + bool handshakeOK; // Is an expected peer side + bool isDead; + string connectKey; + uint8_t connType; // ConnType + uint32_t sessionId; + std::atomic sendRef; + uint8_t uvRef; // libuv handle ref -- just main thread now + uint8_t uvChildRef; // libuv handle ref -- just main thread now + bool childCleared; + map *mapTask; + // class ptr + void *classInstance; // HdcSessionBase instance, HdcServer or HdcDaemon + void *classModule; // Communicate module, TCP or USB instance,HdcDaemonUSB HdcDaemonTCP etc... + // io cache + int bufSize; // total buffer size + int availTailIndex; // buffer available data size + uint8_t *ioBuf; + // auth + list *listKey; // rsa private or publickey list + uint8_t authKeyIndex; + string tokenRSA; // SHA_DIGEST_LENGTH+1==21 + // child work + uv_loop_t childLoop; // run in work thread + // pipe0 in main thread(hdc server mainloop), pipe1 in work thread + uv_tcp_t ctrlPipe[2]; // control channel + int ctrlFd[2]; // control channel socketpair + // data channel(TCP with socket, USB with thread forward) + uv_tcp_t dataPipe[2]; + int dataFd[2]; // data channel socketpair + uv_tcp_t hChildWorkTCP; // work channel,separate thread for server/daemon + uv_os_sock_t fdChildWorkTCP; + // usb handle + HUSB hUSB; + // tcp handle + uv_tcp_t hWorkTCP; + uv_thread_t hWorkThread; + uv_thread_t hWorkChildThread; +}; +using HSession = struct HdcSession *; + +struct HdcChannel { + void *clsChannel; // ptr Class of serverForClient or client + uint32_t channelId; + string connectKey; + uv_tcp_t hWorkTCP; // work channel for client, forward channel for server + uv_thread_t hWorkThread; + uint8_t uvRef = 0; // libuv handle ref -- just main thread now + bool handshakeOK; + bool isDead; + bool serverOrClient; // client's channel/ server's channel + bool childCleared; + bool interactiveShellMode; // Is shell interactive mode + bool keepAlive; // channel will not auto-close by server + std::atomic sendRef; + uint32_t targetSessionId; + // child work + uv_tcp_t hChildWorkTCP; // work channel for server, no use in client + uv_os_sock_t fdChildWorkTCP; + // read io cache + int bufSize; // total buffer size + int availTailIndex; // buffer available data size + uint8_t *ioBuf; + // std + uv_tty_t stdinTty; + uv_tty_t stdoutTty; + char bufStd[128]; +}; +using HChannel = struct HdcChannel *; + +struct HdcDaemonInformation { + uint8_t connType; + uint8_t connStatus; + string connectKey; + string usbMountPoint; + string devName; + HSession hSession; +}; +using HDaemonInfo = struct HdcDaemonInformation *; + +struct HdcForwardInformation { + string taskString; + bool forwardDirection; // true for forward, false is reverse; + uint32_t sessionId; + uint32_t channelId; +}; +using HForwardInfo = struct HdcForwardInformation *; +} +#endif \ No newline at end of file diff --git a/services/flashd/common/file.cpp b/services/flashd/common/file.cpp new file mode 100755 index 00000000..4e3cd905 --- /dev/null +++ b/services/flashd/common/file.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "file.h" +#include "serial_struct.h" + +namespace Hdc { +HdcFile::HdcFile(HTaskInfo hTaskInfo) + : HdcTransferBase(hTaskInfo) +{ + commandBegin = CMD_FILE_BEGIN; + commandData = CMD_FILE_DATA; +} + +HdcFile::~HdcFile() +{ + WRITE_LOG(LOG_DEBUG, "~HdcFile"); +}; + +void HdcFile::StopTask() +{ + WRITE_LOG(LOG_DEBUG, "HdcFile StopTask"); + singalStop = true; +}; + +bool HdcFile::BeginTransfer(CtxFile *context, const string &command) +{ + int argc = 0; + bool ret = false; + char **argv = Base::SplitCommandToArgs(command.c_str(), &argc); + if (argc < CMD_ARG1_COUNT || argv == nullptr) { + LogMsg(MSG_FAIL, "Transfer path split failed"); + if (argv) { + delete[]((char *)argv); + } + return false; + } + if (!SetMasterParameters(context, command.c_str(), argc, argv)) { + delete[]((char *)argv); + return false; + } + do { + ++refCount; + uv_fs_open(loopTask, &context->fsOpenReq, context->localPath.c_str(), O_RDONLY, S_IWUSR | S_IRUSR, OnFileOpen); + context->master = true; + ret = true; + } while (false); + if (!ret) { + LogMsg(MSG_FAIL, "Transfer path failed, Master:%s Slave:%s", context->localPath.c_str(), + context->remotePath.c_str()); + } + delete[]((char *)argv); + return ret; +} + +bool HdcFile::SetMasterParameters(CtxFile *context, const char *command, int argc, char **argv) +{ + int srcArgvIndex = 0; + const string CMD_OPTION_TSTMP = "-a"; + const string CMD_OPTION_SYNC = "-sync"; + const string CMD_OPTION_ZIP = "-z"; + + for (int i = 0; i < argc - CMD_ARG1_COUNT; i++) { + if (argv[i] == CMD_OPTION_ZIP) { + context->transferConfig.compressType = COMPRESS_LZ4; + ++srcArgvIndex; + } else if (argv[i] == CMD_OPTION_SYNC) { + context->transferConfig.updateIfNew = true; + ++srcArgvIndex; + } else if (argv[i] == CMD_OPTION_TSTMP) { + // The time zone difference may cause the display time on the PC and the + // device to differ by several hours + // + // ls -al --full-time + context->transferConfig.holdTimestamp = true; + ++srcArgvIndex; + } else if (argv[i] == CMD_OPTION_CLIENTCWD) { + context->transferConfig.clientCwd = argv[i + 1]; + srcArgvIndex += CMD_ARG1_COUNT; // skip 2args + } else if (argv[i][0] == '-') { + LogMsg(MSG_FAIL, "Unknow file option: %s", argv[i]); + return false; + } + } + context->remotePath = argv[argc - 1]; + context->localPath = argv[argc - 2]; + if (taskInfo->serverOrDaemon) { + // master and server + ExtractRelativePath(context->transferConfig.clientCwd, context->localPath); + } + if (!Base::CheckDirectoryOrPath(context->localPath.c_str(), true, true)) { + LogMsg(MSG_FAIL, "Src not exist, path: %s", context->localPath.c_str()); + return false; + } + context->localName = Base::GetFullFilePath(context->localPath); + return true; +} + +void HdcFile::CheckMaster(CtxFile *context) +{ + string s = SerialStruct::SerializeToString(context->transferConfig); + SendToAnother(CMD_FILE_CHECK, (uint8_t *)s.c_str(), s.size()); +} + +void HdcFile::WhenTransferFinish(CtxFile *context) +{ + WRITE_LOG(LOG_DEBUG, "HdcTransferBase OnFileClose"); + uint8_t flag = 1; + SendToAnother(CMD_FILE_FINISH, &flag, 1); +} + +void HdcFile::TransferSummary(CtxFile *context) +{ + uint64_t nMSec = Base::GetRuntimeMSec() - context->transferBegin; + double fRate = static_cast(context->indexIO) / nMSec; // / /1000 * 1000 = 0 + LogMsg(MSG_OK, "FileTransfer finish, Size:%lld time:%lldms rate:%.2lfkB/s", context->indexIO, nMSec, fRate); +} + +bool HdcFile::SlaveCheck(uint8_t *payload, const int payloadSize) +{ + bool ret = true; + bool childRet = false; + // parse option + string serialStrring((char *)payload, payloadSize); + TransferConfig &stat = ctxNow.transferConfig; + SerialStruct::ParseFromString(stat, serialStrring); + ctxNow.fileSize = stat.fileSize; + ctxNow.localPath = stat.path; + ctxNow.master = false; + ctxNow.fsOpenReq.data = &ctxNow; + // check path + childRet = SmartSlavePath(stat.clientCwd, ctxNow.localPath, stat.optionalName.c_str()); + if (childRet && ctxNow.transferConfig.updateIfNew) { // file exist and option need update + // if is newer + uv_fs_t fs; + Base::ZeroStruct(fs.statbuf); + uv_fs_stat(nullptr, &fs, ctxNow.localPath.c_str(), nullptr); + uv_fs_req_cleanup(&fs); + if ((uint64_t)fs.statbuf.st_mtim.tv_sec >= ctxNow.transferConfig.mtime) { + LogMsg(MSG_FAIL, "Target file is the same date or newer,path: %s", ctxNow.localPath.c_str()); + return false; + } + } + // begin work + ++refCount; + uv_fs_open(loopTask, &ctxNow.fsOpenReq, ctxNow.localPath.c_str(), UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, + S_IWUSR | S_IRUSR, OnFileOpen); + ctxNow.transferBegin = Base::GetRuntimeMSec(); + return ret; +} + +bool HdcFile::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + HdcTransferBase::CommandDispatch(command, payload, payloadSize); + bool ret = true; + switch (command) { + case CMD_FILE_INIT: { // initial + string s = string((char *)payload, payloadSize); + ret = BeginTransfer(&ctxNow, s); + ctxNow.transferBegin = Base::GetRuntimeMSec(); + break; + } + case CMD_FILE_CHECK: { + ret = SlaveCheck(payload, payloadSize); + break; + } + case CMD_FILE_FINISH: { + if (*payload) { // close-step3 + --(*payload); + SendToAnother(CMD_FILE_FINISH, payload, 1); + ++refCount; + uv_fs_close(loopTask, &ctxNow.fsCloseReq, ctxNow.fsOpenReq.result, OnFileClose); + } else { // close-step3 + TransferSummary(&ctxNow); + TaskFinish(); + } + break; + } + default: + break; + } + return ret; +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/file.h b/services/flashd/common/file.h new file mode 100755 index 00000000..230d3f50 --- /dev/null +++ b/services/flashd/common/file.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_FILE_TRANSFER_H +#define HDC_FILE_TRANSFER_H +#include "common.h" +#include "transfer.h" + +namespace Hdc { +class HdcFile : public HdcTransferBase { +public: + HdcFile(HTaskInfo hTaskInfo); + virtual ~HdcFile(); + void StopTask(); + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); + +protected: +private: + bool SlaveCheck(uint8_t *payload, const int payloadSize); + void CheckMaster(CtxFile *context); + void WhenTransferFinish(CtxFile *context); + bool BeginTransfer(CtxFile *context, const string &command); + void TransferSummary(CtxFile *context); + bool SetMasterParameters(CtxFile *context, const char *command, int argc, char **argv); +}; +} // namespace Hdc + +#endif \ No newline at end of file diff --git a/services/flashd/common/file_descriptor.cpp b/services/flashd/common/file_descriptor.cpp new file mode 100755 index 00000000..61886062 --- /dev/null +++ b/services/flashd/common/file_descriptor.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "file_descriptor.h" + +namespace Hdc { +HdcFileDescriptor::HdcFileDescriptor(uv_loop_t *loopIn, int fdToRead, void *callerContextIn, + CallBackWhenRead callbackReadIn, CmdResultCallback callbackFinishIn) +{ + loop = loopIn; + workContinue = true; + callbackFinish = callbackFinishIn; + callbackRead = callbackReadIn; + fdIO = fdToRead; + refIO = 0; + callerContext = callerContextIn; +} + +HdcFileDescriptor::~HdcFileDescriptor() +{ + if (refIO > 0) { + WRITE_LOG(LOG_FATAL, "~HdcFileDescriptor refIO > 0"); + } +} + +bool HdcFileDescriptor::ReadyForRelease() +{ + return refIO == 0; +} + +// just tryCloseFdIo = true, callback will be effect +void HdcFileDescriptor::StopWork(bool tryCloseFdIo, std::function closeFdCallback) +{ + workContinue = false; + callbackCloseFd = closeFdCallback; + if (tryCloseFdIo && refIO > 0) { + ++refIO; + reqClose.data = this; + uv_fs_close(loop, &reqClose, fdIO, [](uv_fs_t *req) { + auto thisClass = (HdcFileDescriptor *)req->data; + uv_fs_req_cleanup(req); + if (thisClass->callbackCloseFd != nullptr) { + thisClass->callbackCloseFd(); + } + --thisClass->refIO; + }); + } +}; + +void HdcFileDescriptor::OnFileIO(uv_fs_t *req) +{ + CtxFileIO *ctxIO = static_cast(req->data); + HdcFileDescriptor *thisClass = ctxIO->thisClass; + uint8_t *buf = ctxIO->bufIO; + bool bFinish = false; + bool fetalFinish = false; + + do { + if (req->result > 0) { + if (req->fs_type == UV_FS_READ) { + if (!thisClass->callbackRead(thisClass->callerContext, buf, req->result)) { + bFinish = true; + break; + } + thisClass->LoopRead(); + } else { + // fs_write + } + } else { + WRITE_LOG(LOG_DEBUG, "OnFileIO fd:%d failed:%s", thisClass->fdIO, uv_strerror(req->result)); + bFinish = true; + fetalFinish = true; + break; + } + } while (false); + uv_fs_req_cleanup(req); + delete[] buf; + delete ctxIO; + + --thisClass->refIO; + if (bFinish) { + thisClass->callbackFinish(thisClass->callerContext, fetalFinish, "OnRead finish"); + thisClass->workContinue = false; + } +} + +int HdcFileDescriptor::LoopRead() +{ + uv_buf_t iov; + int readMax = Base::GetMaxBufSize() * 1.2; + auto contextIO = new CtxFileIO(); + auto buf = new uint8_t[readMax](); + if (!contextIO || !buf) { + if (contextIO) { + delete contextIO; + } + if (buf) { + delete[] buf; + } + WRITE_LOG(LOG_FATAL, "Memory alloc failed"); + callbackFinish(callerContext, true, "Memory alloc failed"); + return -1; + } + uv_fs_t *req = &contextIO->fs; + contextIO->bufIO = buf; + contextIO->thisClass = this; + req->data = contextIO; + ++refIO; + iov = uv_buf_init((char *)buf, readMax); + uv_fs_read(loop, req, fdIO, &iov, 1, -1, OnFileIO); + return 0; +} + +bool HdcFileDescriptor::StartWork() +{ + if (LoopRead() < 0) { + return false; + } + return true; +} + +int HdcFileDescriptor::Write(uint8_t *data, int size) +{ + if (size > static_cast(HDC_BUF_MAX_BYTES)) { + size = static_cast(HDC_BUF_MAX_BYTES); + } + auto buf = new uint8_t[size]; + if (!buf) { + return -1; + } + memcpy_s(buf, size, data, size); + return WriteWithMem(buf, size); +} + +// Data's memory must be Malloc, and the callback FREE after this function is completed +int HdcFileDescriptor::WriteWithMem(uint8_t *data, int size) +{ + auto contextIO = new CtxFileIO(); + if (!contextIO) { + delete[] data; + WRITE_LOG(LOG_FATAL, "Memory alloc failed"); + callbackFinish(callerContext, true, "Memory alloc failed"); + return -1; + } + uv_fs_t *req = &contextIO->fs; + contextIO->bufIO = data; + contextIO->thisClass = this; + req->data = contextIO; + ++refIO; + + uv_buf_t iov = uv_buf_init((char *)data, size); + uv_fs_write(loop, req, fdIO, &iov, 1, -1, OnFileIO); + return size; +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/file_descriptor.h b/services/flashd/common/file_descriptor.h new file mode 100755 index 00000000..40311e71 --- /dev/null +++ b/services/flashd/common/file_descriptor.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_FILE_DESCRIPTOR_H +#define HDC_FILE_DESCRIPTOR_H +#include "common.h" + +namespace Hdc { +class HdcFileDescriptor { +public: + // callerContext, normalFinish, errorString + using CmdResultCallback = std::function; + // callerContext, readBuf, readIOByes + using CallBackWhenRead = std::function; + HdcFileDescriptor(uv_loop_t *loopIn, int fdToRead, void *callerContextIn, CallBackWhenRead callbackReadIn, + CmdResultCallback callbackFinishIn); + virtual ~HdcFileDescriptor(); + int Write(uint8_t *data, int size); + int WriteWithMem(uint8_t *data, int size); + + bool ReadyForRelease(); + bool StartWork(); + void StopWork(bool tryCloseFdIo, std::function closeFdCallback); + +protected: +private: + struct CtxFileIO { + uv_fs_t fs; + uint8_t *bufIO; + HdcFileDescriptor *thisClass; + }; + static void OnFileIO(uv_fs_t *req); + int LoopRead(); + + std::function callbackCloseFd; + CmdResultCallback callbackFinish; + CallBackWhenRead callbackRead; + uv_loop_t *loop; + uv_fs_t reqClose; + void *callerContext; + bool workContinue; + int fdIO; + int refIO; +}; +} // namespace Hdc + +#endif // HDC_FILE_DESCRIPTOR_H \ No newline at end of file diff --git a/services/flashd/common/forward.cpp b/services/flashd/common/forward.cpp new file mode 100755 index 00000000..b096cbb9 --- /dev/null +++ b/services/flashd/common/forward.cpp @@ -0,0 +1,789 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "forward.h" +#include "base.h" + +namespace Hdc { +HdcForwardBase::HdcForwardBase(HTaskInfo hTaskInfo) + : HdcTaskBase(hTaskInfo) +{ +} + +HdcForwardBase::~HdcForwardBase() +{ + WRITE_LOG(LOG_DEBUG, "~HdcForwardBase"); +}; + +bool HdcForwardBase::ReadyForRelease() +{ + if (!HdcTaskBase::ReadyForRelease()) { + return false; + } + return true; +} + +void HdcForwardBase::StopTask() +{ + map::iterator iter; + for (iter = mapCtxPoint.begin(); iter != mapCtxPoint.end(); ++iter) { + HCtxForward ctx = iter->second; + FreeContext(ctx, 0, false); + } + // FREECONTEXT in the STOP is triggered by the other party sector, no longer notifying each other. + mapCtxPoint.clear(); +}; + +void HdcForwardBase::OnAccept(uv_stream_t *server, HCtxForward ctxClient, uv_stream_t *client) +{ + HCtxForward ctxListen = (HCtxForward)server->data; + char buf[BUF_SIZE_DEFAULT] = { 0 }; + bool ret = false; + while (true) { + if (uv_accept(server, client)) { + break; + } + ctxClient->type = ctxListen->type; + ctxClient->remoteParamenters = ctxListen->remoteParamenters; + int maxSize = sizeof(buf) - FORWARD_PARAMENTER_BUFSIZE; + // clang-format off + if (snprintf_s(buf + FORWARD_PARAMENTER_BUFSIZE, maxSize, maxSize - 1, "%s", + ctxClient->remoteParamenters.c_str()) < 0) { + break; + } + // clang-format on + // pre 8bytes preserve for param bits + SendToTask(ctxClient->id, CMD_FORWARD_ACTIVE_SLAVE, (uint8_t *)buf, + strlen(buf + FORWARD_PARAMENTER_BUFSIZE) + 9); + ret = true; + break; + } + if (!ret) { + FreeContext(ctxClient, 0, false); + } +} + +void HdcForwardBase::ListenCallback(uv_stream_t *server, const int status) +{ + HCtxForward ctxListen = (HCtxForward)server->data; + HdcForwardBase *thisClass = ctxListen->thisClass; + uv_stream_t *client = nullptr; + + if (status == -1 || !ctxListen->ready) { + thisClass->FreeContext(ctxListen, 0, false); + thisClass->TaskFinish(); + return; + } + HCtxForward ctxClient = (HCtxForward)thisClass->MallocContext(true); + if (!ctxClient) { + return; + } + if (FORWARD_TCP == ctxListen->type) { + uv_tcp_init(ctxClient->thisClass->loopTask, &ctxClient->tcp); + client = (uv_stream_t *)&ctxClient->tcp; + } else { + // FORWARD_ABSTRACT, FORWARD_RESERVED, FORWARD_FILESYSTEM, + uv_pipe_init(ctxClient->thisClass->loopTask, &ctxClient->pipe, 0); + client = (uv_stream_t *)&ctxClient->pipe; + } + thisClass->OnAccept(server, ctxClient, client); +} + +void *HdcForwardBase::MallocContext(bool masterSlave) +{ + HCtxForward ctx = nullptr; + if ((ctx = new ContextForward()) == nullptr) { + return nullptr; + } + ctx->id = Base::GetRuntimeMSec(); + ctx->masterSlave = masterSlave; + ctx->thisClass = this; + ctx->fdClass = nullptr; + ctx->tcp.data = ctx; + ctx->pipe.data = ctx; + AdminContext(OP_ADD, ctx->id, ctx); + refCount++; + return ctx; +} + +void HdcForwardBase::FreeContextCallBack(HCtxForward ctx) +{ + AdminContext(OP_REMOVE, ctx->id, nullptr); + Base::DoNextLoop(loopTask, ctx, [](const uint8_t flag, string &msg, const void *data) { + HCtxForward ctx = (HCtxForward)data; + delete ctx; + }); + --refCount; +} + +void HdcForwardBase::FreeJDWP(HCtxForward ctx) +{ + if (ctx->fd > 0) { + close(ctx->fd); + } + if (ctx->fdClass) { + ctx->fdClass->StopWork(false, nullptr); + + auto funcReqClose = [](uv_idle_t *handle) -> void { + uv_close_cb funcIdleHandleClose = [](uv_handle_t *handle) -> void { + HCtxForward ctx = (HCtxForward)handle->data; + ctx->thisClass->FreeContextCallBack(ctx); + delete (uv_idle_t *)handle; + }; + HCtxForward ctx = (HCtxForward)handle->data; + if (ctx->fdClass->ReadyForRelease()) { + delete ctx->fdClass; + ctx->fdClass = nullptr; + Base::TryCloseHandle((uv_handle_t *)handle, funcIdleHandleClose); + } + }; + Base::IdleUvTask(loopTask, ctx, funcReqClose); + } +} + +void HdcForwardBase::FreeContext(HCtxForward ctxIn, const uint32_t id, bool bNotifyRemote) +{ + WRITE_LOG(LOG_DEBUG, "FreeContext bNotifyRemote:%d %p", bNotifyRemote, ctxIn); + HCtxForward ctx = nullptr; + if (!ctxIn) { + if (!(ctx = (HCtxForward)AdminContext(OP_QUERY, id, nullptr))) { + WRITE_LOG(LOG_DEBUG, "Query id failed"); + return; + } + } else { + ctx = ctxIn; + } + if (ctx->finish) { + return; + } + if (bNotifyRemote) { + SendToTask(ctx->id, CMD_FORWARD_FREE_CONTEXT, nullptr, 0); + } + uv_close_cb funcHandleClose = [](uv_handle_t *handle) -> void { + HCtxForward ctx = (HCtxForward)handle->data; + ctx->thisClass->FreeContextCallBack(ctx); + }; + switch (ctx->type) { + case FORWARD_TCP: + case FORWARD_JDWP: + Base::TryCloseHandle((uv_handle_t *)&ctx->tcp, true, funcHandleClose); + break; + case FORWARD_ABSTRACT: + case FORWARD_RESERVED: + case FORWARD_FILESYSTEM: + Base::TryCloseHandle((uv_handle_t *)&ctx->pipe, true, funcHandleClose); + break; + case FORWARD_DEVICE: { + FreeJDWP(ctx); + break; + } + default: + break; + } + ctx->finish = true; +} + +bool HdcForwardBase::SendToTask(const uint32_t cid, const uint16_t command, uint8_t *bufPtr, const int bufSize) +{ + bool ret = false; + // usually MAX_SIZE_IOBUF*2 from HdcFileDescriptor maxIO + if (bufSize > Base::GetMaxBufSize() * 2) { + return false; + } + auto newBuf = new uint8_t[bufSize + 4]; + if (!newBuf) { + return false; + } + *(uint32_t *)(newBuf) = htonl(cid); + if (bufSize > 0 && bufPtr != nullptr && memcpy_s(newBuf + 4, bufSize, bufPtr, bufSize) != EOK) { + delete[] newBuf; + return false; + } + ret = SendToAnother(command, newBuf, bufSize + 4); + delete[] newBuf; + return ret; +} + +// Forward flow is small and frequency is fast +void HdcForwardBase::AllocForwardBuf(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf) +{ + const uint16_t size = 1492 - 256; // For layer 3, the default MTU is 1492 bytes. reserve hdc header 256 bytes + buf->base = (char *)new char[size]; + if (buf->base) { + buf->len = size - 1; + } else { + WRITE_LOG(LOG_WARN, "AllocForwardBuf == null"); + } +} + +void HdcForwardBase::ReadForwardBuf(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) +{ + HCtxForward ctx = (HCtxForward)stream->data; + if (nread < 0) { + ctx->thisClass->FreeContext(ctx, 0, true); + return; + } + ctx->thisClass->SendToTask(ctx->id, CMD_FORWARD_DATA, (uint8_t *)buf->base, nread); + // clear + delete[] buf->base; +} + +void HdcForwardBase::ConnectTarget(uv_connect_t *connection, int status) +{ + HCtxForward ctx = (HCtxForward)connection->data; + HdcForwardBase *thisClass = ctx->thisClass; + delete connection; + if (status < 0) { + WRITE_LOG(LOG_WARN, "Forward connect result:%d error:%s", status, uv_err_name(status)); + } + thisClass->SetupPointContinue(ctx, status); +} + +bool HdcForwardBase::CheckNodeInfo(const char *nodeInfo, string as[2]) +{ + char bufString[BUF_SIZE_MEDIUM]; + if (!strchr(nodeInfo, ':')) { + return false; + } + if (EOK != strcpy_s(bufString, sizeof(bufString), nodeInfo)) { + return false; + } + if (*strchr(bufString, ':')) { + *strchr(bufString, ':') = '\0'; + } else { + return false; + } + as[0] = bufString; + as[1] = bufString + strlen(bufString) + 1; + if (as[0].size() > BUF_SIZE_SMALL || as[1].size() > BUF_SIZE_SMALL) { + return false; + } + if (as[0] == "tcp") { + int port = atoi(as[1].c_str()); + if (port <= 0 || port > MAX_IP_PORT) { + return false; + } + } + return true; +} + +bool HdcForwardBase::SetupPointContinue(HCtxForward ctx, int status) +{ + if (ctx->checkPoint) { + // send to active + uint8_t flag = status > 0; + SendToTask(ctx->id, CMD_FORWARD_CHECK_RESULT, &flag, 1); + FreeContext(ctx, 0, false); + return true; + } + if (status < 0) { + FreeContext(ctx, 0, true); + return false; + } + // send to active + if (!SendToTask(ctx->id, CMD_FORWARD_ACTIVE_MASTER, nullptr, 0)) { + FreeContext(ctx, 0, true); + return false; + } + return DoForwardBegin(ctx); +} + +bool HdcForwardBase::DetechForwardType(HCtxForward ctxPoint) +{ + string &sFType = ctxPoint->localArgs[0]; + string &sNodeCfg = ctxPoint->localArgs[1]; + // string to enum + if (sFType == "tcp") { + ctxPoint->type = FORWARD_TCP; + } else if (sFType == "dev") { + ctxPoint->type = FORWARD_DEVICE; + } else if (sFType == "localabstract") { + // daemon shell: /system/bin/socat abstract-listen:linux-abstract - + // daemon shell: /system/bin/socat - abstract-connect:linux-abstract + // host: hdc_std fport tcp:8080 localabstract:linux-abstract + ctxPoint->type = FORWARD_ABSTRACT; + } else if (sFType == "localreserved") { + sNodeCfg = HARMONY_RESERVED_SOCKET_PREFIX + sNodeCfg; + ctxPoint->type = FORWARD_RESERVED; + } else if (sFType == "localfilesystem") { + sNodeCfg = FILESYSTEM_SOCKET_PREFIX + sNodeCfg; + ctxPoint->type = FORWARD_FILESYSTEM; + } else if (sFType == "jdwp") { + ctxPoint->type = FORWARD_JDWP; + } else { + return false; + } + return true; +} + +bool HdcForwardBase::SetupTCPPoint(HCtxForward ctxPoint) +{ + string &sNodeCfg = ctxPoint->localArgs[1]; + int port = atoi(sNodeCfg.c_str()); + ctxPoint->tcp.data = ctxPoint; + uv_tcp_init(loopTask, &ctxPoint->tcp); + struct sockaddr_in addr; + if (ctxPoint->masterSlave) { + uv_ip4_addr("0.0.0.0", port, &addr); // loop interface + uv_tcp_bind(&ctxPoint->tcp, (const struct sockaddr *)&addr, 0); + if (uv_listen((uv_stream_t *)&ctxPoint->tcp, 4, ListenCallback)) { + ctxPoint->lastError = "TCP Port listen failed at " + sNodeCfg; + return false; + } + } else { + uv_ip4_addr("127.0.0.1", port, &addr); // loop interface + uv_connect_t *conn = new uv_connect_t(); + conn->data = ctxPoint; + uv_tcp_connect(conn, (uv_tcp_t *)&ctxPoint->tcp, (const struct sockaddr *)&addr, ConnectTarget); + } + return true; +} + +bool HdcForwardBase::SetupDevicePoint(HCtxForward ctxPoint) +{ + uint8_t flag = 1; + string &sNodeCfg = ctxPoint->localArgs[1]; + string resolvedPath = Base::CanonicalizeSpecPath(sNodeCfg); + if ((ctxPoint->fd = open(resolvedPath.c_str(), O_RDWR)) < 0) { + ctxPoint->lastError = "Open unix-dev failed"; + flag = -1; + } + auto funcRead = [&](const void *a, uint8_t *b, const int c) -> bool { + HCtxForward ctx = (HCtxForward)a; + return SendToTask(ctx->id, CMD_FORWARD_DATA, b, c); + }; + auto funcFinish = [&](const void *a, const bool b, const string c) -> bool { + HCtxForward ctx = (HCtxForward)a; + WRITE_LOG(LOG_DEBUG, "Error ReadForwardBuf dev,ret:%d reson:%s", b, c.c_str()); + FreeContext(ctx, 0, true); + return false; + }; + ctxPoint->fdClass = new HdcFileDescriptor(loopTask, ctxPoint->fd, ctxPoint, funcRead, funcFinish); + SetupPointContinue(ctxPoint, flag); + return true; +} + +bool HdcForwardBase::LocalAbstractConnect(uv_pipe_t *pipe, string &sNodeCfg) +{ + bool abstractRet = false; +#ifndef _WIN32 + int s = 0; + do { + if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { + break; + } + fcntl(s, F_SETFD, FD_CLOEXEC); + struct sockaddr_un addr; + Base::ZeroStruct(addr); + int addrLen = sNodeCfg.size() + offsetof(struct sockaddr_un, sun_path) + 1; + addr.sun_family = AF_LOCAL; + addr.sun_path[0] = 0; + + if (memcpy_s(addr.sun_path + 1, sizeof(addr.sun_path) - 1, sNodeCfg.c_str(), sNodeCfg.size()) != EOK) { + break; + }; + // local connect, ignore timeout + if (connect(s, (struct sockaddr *)&addr, addrLen) < 0) { + break; + } + if (uv_pipe_open(pipe, s)) { + break; + } + abstractRet = true; + } while (false); + if (!abstractRet && s > 0) { + close(s); + } +#endif + return abstractRet; +} + +bool HdcForwardBase::SetupFilePoint(HCtxForward ctxPoint) +{ + string &sNodeCfg = ctxPoint->localArgs[1]; + ctxPoint->pipe.data = ctxPoint; + uv_pipe_init(loopTask, &ctxPoint->pipe, 0); + if (ctxPoint->masterSlave) { + if (ctxPoint->type == FORWARD_RESERVED || ctxPoint->type == FORWARD_FILESYSTEM) { + unlink(sNodeCfg.c_str()); + } + if (uv_pipe_bind(&ctxPoint->pipe, sNodeCfg.c_str())) { + ctxPoint->lastError = "Unix pipe bind failed"; + return false; + } + if (uv_listen((uv_stream_t *)&ctxPoint->pipe, 4, ListenCallback)) { + ctxPoint->lastError = "Unix pipe listen failed"; + return false; + } + } else { + uv_connect_t *connect = new uv_connect_t(); + connect->data = ctxPoint; + if (ctxPoint->type == FORWARD_ABSTRACT) { + bool abstractRet = LocalAbstractConnect(&ctxPoint->pipe, sNodeCfg); + SetupPointContinue(ctxPoint, abstractRet ? 0 : -1); + if (!abstractRet) { + ctxPoint->lastError = "LocalAbstractConnect failed"; + return false; + } + } else { + uv_pipe_connect(connect, &ctxPoint->pipe, sNodeCfg.c_str(), ConnectTarget); + } + } + return true; +} + +bool HdcForwardBase::SetupPoint(HCtxForward ctxPoint) +{ + bool ret = true; + if (!DetechForwardType(ctxPoint)) { + return false; + } + switch (ctxPoint->type) { + case FORWARD_TCP: + if (!SetupTCPPoint(ctxPoint)) { + ret = false; + }; + break; +#ifndef _WIN32 + case FORWARD_DEVICE: + if (!SetupDevicePoint(ctxPoint)) { + ret = false; + }; + break; + case FORWARD_JDWP: + if (!SetupJdwpPoint(ctxPoint)) { + ret = false; + }; + break; + case FORWARD_ABSTRACT: + case FORWARD_RESERVED: + case FORWARD_FILESYSTEM: + if (!SetupFilePoint(ctxPoint)) { + ret = false; + }; + break; +#else + case FORWARD_DEVICE: + case FORWARD_JDWP: + case FORWARD_ABSTRACT: + case FORWARD_RESERVED: + case FORWARD_FILESYSTEM: + ctxPoint->lastError = "Not supoort forward-type"; + ret = false; + break; +#endif + default: + ctxPoint->lastError = "Not supoort forward-type"; + ret = false; + break; + } + return ret; +} + +bool HdcForwardBase::BeginForward(const char *command, string &sError) +{ + bool ret = false; + int argc = 0; + char bufString[BUF_SIZE_SMALL] = ""; + HCtxForward ctxPoint = (HCtxForward)MallocContext(true); + if (!ctxPoint) { + WRITE_LOG(LOG_FATAL, "MallocContext failed"); + return false; + } + char **argv = Base::SplitCommandToArgs(command, &argc); + while (true) { + if (argc < CMD_ARG1_COUNT) { + break; + } + if (strlen(argv[0]) > BUF_SIZE_SMALL || strlen(argv[1]) > BUF_SIZE_SMALL) { + break; + } + if (!CheckNodeInfo(argv[0], ctxPoint->localArgs)) { + break; + } + if (!CheckNodeInfo(argv[1], ctxPoint->remoteArgs)) { + break; + } + ctxPoint->remoteParamenters = argv[1]; + if (!SetupPoint(ctxPoint)) { + break; + } + + ret = true; + break; + } + sError = ctxPoint->lastError; + if (ret) { + // First 8-byte parameter bit + int maxBufSize = sizeof(bufString) - FORWARD_PARAMENTER_BUFSIZE; + if (snprintf_s(bufString + FORWARD_PARAMENTER_BUFSIZE, maxBufSize, maxBufSize - 1, "%s", argv[1]) > 0) { + SendToTask(ctxPoint->id, CMD_FORWARD_CHECK, (uint8_t *)bufString, + FORWARD_PARAMENTER_BUFSIZE + strlen(bufString + FORWARD_PARAMENTER_BUFSIZE) + 1); + taskCommand = command; + } + } + if (argv) { + delete[]((char *)argv); + } + return ret; +} + +inline bool HdcForwardBase::FilterCommand(uint8_t *bufCmdIn, uint32_t *idOut, uint8_t **pContentBuf) +{ + *pContentBuf = bufCmdIn + DWORD_SERIALIZE_SIZE; + *idOut = ntohl(*(uint32_t *)bufCmdIn); + return true; +} + +bool HdcForwardBase::SlaveConnect(uint8_t *bufCmd, bool bCheckPoint, string &sError) +{ + bool ret = false; + char *content = nullptr; + uint32_t idSlaveOld = 0; + HCtxForward ctxPoint = (HCtxForward)MallocContext(false); + if (!ctxPoint) { + WRITE_LOG(LOG_FATAL, "MallocContext failed"); + return false; + } + idSlaveOld = ctxPoint->id; + ctxPoint->checkPoint = bCheckPoint; + // refresh another id,8byte param + FilterCommand(bufCmd, &ctxPoint->id, (uint8_t **)&content); + AdminContext(OP_UPDATE, idSlaveOld, ctxPoint); + content += FORWARD_PARAMENTER_BUFSIZE; + if (!CheckNodeInfo(content, ctxPoint->localArgs)) { + return false; + } + if ((ctxPoint->checkPoint && slaveCheckWhenBegin) || !ctxPoint->checkPoint) { + if (!SetupPoint(ctxPoint)) { + WRITE_LOG(LOG_FATAL, "SetupPoint failed"); + goto Finish; + } + sError = ctxPoint->lastError; + } else { + SetupPointContinue(ctxPoint, 0); + } + ret = true; +Finish: + if (!ret) { + FreeContext(ctxPoint, 0, true); + } + return ret; +} + +bool HdcForwardBase::DoForwardBegin(HCtxForward ctx) +{ + switch (ctx->type) { + case FORWARD_TCP: + case FORWARD_JDWP: // jdwp use tcp ->socketpair->jvm + uv_tcp_nodelay((uv_tcp_t *)&ctx->tcp, 1); + uv_read_start((uv_stream_t *)&ctx->tcp, AllocForwardBuf, ReadForwardBuf); + break; + case FORWARD_ABSTRACT: + case FORWARD_RESERVED: + case FORWARD_FILESYSTEM: + uv_read_start((uv_stream_t *)&ctx->pipe, AllocForwardBuf, ReadForwardBuf); + break; + case FORWARD_DEVICE: { + ctx->fdClass->StartWork(); + break; + } + default: + break; + } + ctx->ready = true; + return true; +} + +void *HdcForwardBase::AdminContext(const uint8_t op, const uint32_t id, HCtxForward hInput) +{ + void *hRet = nullptr; + map &mapCtx = mapCtxPoint; + switch (op) { + case OP_ADD: + mapCtx[id] = hInput; + break; + case OP_REMOVE: + mapCtx.erase(id); + break; + case OP_QUERY: + if (mapCtx.count(id)) { + hRet = mapCtx[id]; + } + break; + case OP_UPDATE: + mapCtx.erase(id); + mapCtx[hInput->id] = hInput; + break; + default: + break; + } + return hRet; +} + +void HdcForwardBase::SendCallbackForwardBuf(uv_write_t *req, int status) +{ + ContextForwardIO *ctxIO = (ContextForwardIO *)req->data; + HCtxForward ctx = (HCtxForward)ctxIO->ctxForward; + if (status < 0 && !ctx->finish) { + WRITE_LOG(LOG_DEBUG, "SendCallbackForwardBuf ctx->type:%d, status:%d finish", ctx->type, status); + ctx->thisClass->FreeContext(ctx, 0, true); + } + delete[] ctxIO->bufIO; + delete ctxIO; + delete req; +} + +int HdcForwardBase::SendForwardBuf(HCtxForward ctx, uint8_t *bufPtr, const int size) +{ + int nRet = 0; + if (size > static_cast(HDC_BUF_MAX_BYTES)) { + return -1; + } + auto pDynBuf = new uint8_t[size]; + if (!pDynBuf) { + return -1; + } + memcpy_s(pDynBuf, size, bufPtr, size); + if (FORWARD_DEVICE == ctx->type) { + nRet = ctx->fdClass->WriteWithMem(pDynBuf, size); + } else { + auto ctxIO = new ContextForwardIO(); + if (!ctxIO) { + delete[] pDynBuf; + return -1; + } + ctxIO->ctxForward = ctx; + ctxIO->bufIO = pDynBuf; + if (FORWARD_TCP == ctx->type || FORWARD_JDWP == ctx->type) { + nRet = Base::SendToStreamEx((uv_stream_t *)&ctx->tcp, pDynBuf, size, nullptr, + (void *)SendCallbackForwardBuf, (void *)ctxIO); + } else { + // FORWARD_ABSTRACT, FORWARD_RESERVED, FORWARD_FILESYSTEM, + nRet = Base::SendToStreamEx((uv_stream_t *)&ctx->pipe, pDynBuf, size, nullptr, + (void *)SendCallbackForwardBuf, (void *)ctxIO); + } + } + return nRet; +} + +bool HdcForwardBase::CommandForwardCheckResult(HCtxForward ctx, uint8_t *payload) +{ + bool ret = true; + bool bCheck = (bool)payload; + LogMsg(bCheck ? MSG_OK : MSG_FAIL, "Forwardport result:%s", bCheck ? "OK" : "Failed"); + if (bCheck) { + string mapInfo = taskInfo->serverOrDaemon ? "1|" : "0|"; + mapInfo += taskCommand; + ctx->ready = true; + ServerCommand(CMD_FORWARD_SUCCESS, (uint8_t *)mapInfo.c_str(), mapInfo.size() + 1); + } else { + ret = false; + FreeContext(ctx, 0, false); + } + return ret; +} + +bool HdcForwardBase::ForwardCommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + bool ret = true; + uint8_t *pContent = nullptr; + int sizeContent = 0; + uint32_t id = 0; + HCtxForward ctx = nullptr; + FilterCommand(payload, &id, &pContent); + sizeContent = payloadSize - DWORD_SERIALIZE_SIZE; + if (!(ctx = (HCtxForward)AdminContext(OP_QUERY, id, nullptr))) { + WRITE_LOG(LOG_WARN, "Query id failed"); + return false; + } + switch (command) { + case CMD_FORWARD_CHECK_RESULT: { + ret = CommandForwardCheckResult(ctx, payload); + break; + } + case CMD_FORWARD_ACTIVE_MASTER: { + ret = DoForwardBegin(ctx); + break; + } + case CMD_FORWARD_DATA: { + if (ctx->finish) { + break; + } + if (SendForwardBuf(ctx, pContent, sizeContent) < 0) { + FreeContext(ctx, 0, true); + } + break; + } + case CMD_FORWARD_FREE_CONTEXT: { + FreeContext(ctx, 0, false); + break; + } + default: + ret = false; + break; + } + if (!ret) { + if (ctx) { + FreeContext(ctx, 0, true); + } else { + WRITE_LOG(LOG_DEBUG, "ctx==nullptr raw free"); + TaskFinish(); + } + } + return ret; +} + +bool HdcForwardBase::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + bool ret = true; + string sError; + // prepare + if (CMD_FORWARD_INIT == command) { + if (!BeginForward((char *)(payload), sError)) { + ret = false; + goto Finish; + } + return true; + } else if (CMD_FORWARD_CHECK == command) { + // Detect remote if it's reachable + if (!SlaveConnect(payload, true, sError)) { + ret = false; + goto Finish; + } + return true; + } else if (CMD_FORWARD_ACTIVE_SLAVE == command) { + // slave connect target port when activating + if (!SlaveConnect(payload, false, sError)) { + ret = false; + goto Finish; + } + return true; + } + if (!ForwardCommandDispatch(command, payload, payloadSize)) { + ret = false; + goto Finish; + } +Finish: + if (!ret) { + if (!sError.size()) { + LogMsg(MSG_FAIL, "Forward parament failed"); + } else { + LogMsg(MSG_FAIL, (char *)sError.c_str()); + WRITE_LOG(LOG_WARN, (char *)sError.c_str()); + } + } + return ret; +} +} // namespace Hdc diff --git a/services/flashd/common/forward.h b/services/flashd/common/forward.h new file mode 100755 index 00000000..9baf4702 --- /dev/null +++ b/services/flashd/common/forward.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_FORWARD_H +#define HDC_FORWARD_H +#include "common.h" + +namespace Hdc { +class HdcForwardBase : public HdcTaskBase { +public: + HdcForwardBase(HTaskInfo hTaskInfo); + virtual ~HdcForwardBase(); + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); + bool BeginForward(const char *command, string &sError); + void StopTask(); + bool ReadyForRelease(); + +protected: + enum FORWARD_TYPE { + FORWARD_TCP, + FORWARD_DEVICE, + FORWARD_JDWP, + FORWARD_ABSTRACT, + FORWARD_RESERVED, + FORWARD_FILESYSTEM, + }; + struct ContextForward { + FORWARD_TYPE type; + bool masterSlave; + bool checkPoint; + bool ready; + bool finish; + int fd; + uint32_t id; + uv_tcp_t tcp; + uv_pipe_t pipe; + HdcFileDescriptor *fdClass; + HdcForwardBase *thisClass; + string path; + string lastError; + string localArgs[2]; + string remoteArgs[2]; + string remoteParamenters; + }; + using HCtxForward = struct ContextForward *; + struct ContextForwardIO { + HCtxForward ctxForward; + uint8_t *bufIO; + }; + + virtual bool SetupJdwpPoint(HCtxForward ctxPoint) + { + return false; + } + bool SetupPointContinue(HCtxForward ctx, int status); + +private: + static void ListenCallback(uv_stream_t *server, const int status); + static void ConnectTarget(uv_connect_t *connection, int status); + static void ReadForwardBuf(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); + static void AllocForwardBuf(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf); + static void SendCallbackForwardBuf(uv_write_t *req, int status); + static void OnFdRead(uv_fs_t *req); + + bool SetupPoint(HCtxForward ctxPoint); + void *MallocContext(bool masterSlave); + bool SlaveConnect(uint8_t *bufCmd, bool bCheckPoint, string &sError); + bool SendToTask(const uint32_t cid, const uint16_t command, uint8_t *bufPtr, const int bufSize); + bool FilterCommand(uint8_t *bufCmdIn, uint32_t *idOut, uint8_t **pContentBuf); + void *AdminContext(const uint8_t op, const uint32_t id, HCtxForward hInput); + bool DoForwardBegin(HCtxForward ctx); + int SendForwardBuf(HCtxForward ctx, uint8_t *bufPtr, const int size); + bool CheckNodeInfo(const char *nodeInfo, string as[2]); + void FreeContext(HCtxForward ctxIn, const uint32_t id, bool bNotifyRemote); + int LoopFdRead(HCtxForward ctx); + void FreeContextCallBack(HCtxForward ctx); + void FreeJDWP(HCtxForward ctx); + void OnAccept(uv_stream_t *server, HCtxForward ctxClient, uv_stream_t *client); + bool DetechForwardType(HCtxForward ctxPoint); + bool SetupTCPPoint(HCtxForward ctxPoint); + bool SetupDevicePoint(HCtxForward ctxPoint); + bool SetupFilePoint(HCtxForward ctxPoint); + bool ForwardCommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); + bool CommandForwardCheckResult(HCtxForward ctx, uint8_t *payload); + bool LocalAbstractConnect(uv_pipe_t *pipe, string &sNodeCfg); + + map mapCtxPoint; + string taskCommand; + const uint8_t FORWARD_PARAMENTER_BUFSIZE = 8; + const string FILESYSTEM_SOCKET_PREFIX = "/tmp/"; + const string HARMONY_RESERVED_SOCKET_PREFIX = "/dev/socket/"; + // set true to enable slave check when forward create + const bool slaveCheckWhenBegin = false; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/common/serial_struct.h b/services/flashd/common/serial_struct.h new file mode 100755 index 00000000..b151f9dc --- /dev/null +++ b/services/flashd/common/serial_struct.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_SERIAL_STRUCT_H +#define HDC_SERIAL_STRUCT_H +#include "common.h" +#include "serial_struct_define.h" +#include "transfer.h" + +namespace Hdc { +namespace SerialStruct { + constexpr int fieldOne = 1; + constexpr int fieldTwo = 2; + constexpr int fieldThree = 3; + constexpr int fieldFour = 4; + constexpr int fieldFive = 5; + constexpr int fieldSix = 6; + constexpr int fieldSeven = 7; + constexpr int fieldEight = 8; + constexpr int fieldNine = 9; + constexpr int fieldTen = 10; + constexpr int field11 = 11; + constexpr int field12 = 12; + constexpr int field13 = 13; + + template<> struct Descriptor { + static auto type() + { + return Message(Field("fileSize"), + Field("atime"), + Field("mtime"), + Field("options"), + Field("path"), + Field("optionalName"), + Field("updateIfNew"), + Field("compressType"), + Field("holdTimestamp"), + Field("functionName"), + Field("clientCwd"), + Field("reserve1"), + Field("reserve2")); + } + }; + + template<> struct Descriptor { + static auto type() + { + return Message(Field("index"), + Field("compressType"), + Field("compressSize"), + Field("uncompressSize")); + } + }; + + template<> struct Descriptor { + static auto type() + { + return Message(Field("banner"), + Field("authType"), + Field("sessionId"), + Field("connectKey"), + Field("buf")); + } + }; + + template<> struct Descriptor { + static auto type() + { + return Message(Field("channelId"), + Field("commandFlag"), + Field("checkSum"), + Field("vCode")); + } + }; +} // SerialStruct +} // Hdc +#endif // HDC_SERIAL_STRUCT_H diff --git a/services/flashd/common/serial_struct_define.h b/services/flashd/common/serial_struct_define.h new file mode 100755 index 00000000..f2beb1cd --- /dev/null +++ b/services/flashd/common/serial_struct_define.h @@ -0,0 +1,1314 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_SERIAL_STRUCT_DEFINE_H +#define HDC_SERIAL_STRUCT_DEFINE_H +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// static file define. No need not modify. by zako +namespace Hdc { +// clang-format off +namespace SerialStruct { + namespace SerialDetail { + template struct MemPtr { + }; + template struct MemPtr { + using type = T; + using MemberType = U; + }; + template struct MessageImpl { + public: + MessageImpl(Fields &&... fields) + : _fields(std::move(fields)...) + { + } + + template void Visit(Handler &&handler) const + { + VisitImpl(std::forward(handler), std::make_index_sequence()); + } + + private: + std::tuple _fields; + + template void VisitImpl(Handler &&handler, std::index_sequence) const + { + (handler(std::get(_fields)), ...); + } + }; + + template struct FieldImpl { + using type = typename SerialDetail::MemPtr::type; + using MemberType = typename SerialDetail::MemPtr::MemberType; + constexpr static const uint32_t tag = Tag; + constexpr static const uint32_t flags = Flags; + const std::string field_name; + + static decltype(auto) get(const type &value) + { + return value.*MemPtr; + } + + static decltype(auto) get(type &value) + { + return value.*MemPtr; + } + }; + + template struct OneofFieldImpl { + using type = typename SerialDetail::MemPtr::type; + using MemberType = typename SerialDetail::MemPtr::MemberType; + constexpr static const uint32_t tag = Tag; + constexpr static const size_t index = Index; + constexpr static const uint32_t flags = Flags; + const std::string field_name; + + static decltype(auto) get(const type &value) + { + return value.*MemPtr; + } + + static decltype(auto) get(type &value) + { + return value.*MemPtr; + } + }; + + template + struct MapFieldImpl { + using type = typename SerialDetail::MemPtr::type; + using MemberType = typename SerialDetail::MemPtr::MemberType; + constexpr static const uint32_t tag = Tag; + constexpr static const uint32_t KEY_FLAGS = KeyFlags; + constexpr static const uint32_t VALUE_FLAGS = ValueFlags; + + const std::string field_name; + + static decltype(auto) get(const type &value) + { + return value.*MemPtr; + } + + static decltype(auto) get(type &value) + { + return value.*MemPtr; + } + }; + } + + enum class WireType : uint32_t { + VARINT = 0, + FIXED64 = 1, + LENGTH_DELIMETED = 2, + START_GROUP = 3, + END_GROUP = 4, + FIXED32 = 5, + }; + enum flags { no = 0, s = 1, f = 2 }; + template struct FlagsType { + }; + + template struct Descriptor { + static_assert(sizeof(T) == 0, "You need to implement descriptor for your own types"); + static void type() + { + } + }; + + template constexpr auto Message(Fields &&... fields) + { + return SerialDetail::MessageImpl(std::forward(fields)...); + } + + template constexpr auto Field(const std::string &fieldName) + { + return SerialDetail::FieldImpl { fieldName }; + } + + template + constexpr auto OneofField(const std::string &fieldName) + { + return SerialDetail::OneofFieldImpl { fieldName }; + } + + template + constexpr auto MapField(const std::string &fieldName) + { + return SerialDetail::MapFieldImpl { fieldName }; + } + + template const auto &MessageType() + { + static const auto message = Descriptor::type(); + return message; + } + + template struct Serializer; + + struct Writer { + virtual void Write(const void *bytes, size_t size) = 0; + }; + + struct reader { + virtual size_t Read(void *bytes, size_t size) = 0; + }; + + namespace SerialDetail { + template + struct HasSerializePacked : public std::false_type { + }; + + template + struct HasSerializePacked().SerializePacked( + std::declval(), std::declval(), std::declval()))>> : public std::true_type { + }; + + template + constexpr bool HAS_SERIALIZE_PACKED_V = HasSerializePacked::value; + + template + struct HasParsePacked : public std::false_type { + }; + + template + struct HasParsePacked().ParsePacked( + std::declval(), std::declval(), std::declval()))>> : public std::true_type { + }; + + template + constexpr bool HAS_PARSE_PACKED_V = HasParsePacked::value; + + static uint32_t MakeTagWireType(uint32_t tag, WireType wireType) + { + return (tag << 3) | static_cast(wireType); + } + + static inline void ReadTagWireType(uint32_t tagKey, uint32_t &tag, WireType &wireType) + { + wireType = static_cast(tagKey & 0b0111); + tag = tagKey >> 3; + } + + static uint32_t MakeZigzagValue(int32_t value) + { + return (static_cast(value) << 1) ^ static_cast(value >> 31); + } + + static uint64_t MakeZigzagValue(int64_t value) + { + return (static_cast(value) << 1) ^ static_cast(value >> 63); + } + + static int32_t ReadZigzagValue(uint32_t value) + { + return static_cast((value >> 1) ^ (~(value & 1) + 1)); + } + + static int64_t ReadZigzagValue(uint64_t value) + { + return static_cast((value >> 1) ^ (~(value & 1) + 1)); + } + + template To BitCast(From from) + { + static_assert(sizeof(To) == sizeof(From), ""); + static_assert(std::is_trivially_copyable_v, ""); + static_assert(std::is_trivially_copyable_v, ""); + To to; + memcpy_s(&to, sizeof(To), &from, sizeof(from)); + return to; + } + + struct WriterSizeCollector : public Writer { + void Write(const void *, size_t size) override + { + byte_size += size; + } + size_t byte_size = 0; + }; + + struct LimitedReader : public reader { + LimitedReader(reader &parent, size_t sizeLimit) + : _parent(parent), _size_limit(sizeLimit) + { + } + + size_t Read(void *bytes, size_t size) + { + auto sizeToRead = std::min(size, _size_limit); + auto readSize = _parent.Read(bytes, sizeToRead); + _size_limit -= readSize; + return readSize; + } + + size_t AvailableBytes() const + { + return _size_limit; + } + + private: + reader &_parent; + size_t _size_limit; + }; + + static bool ReadByte(uint8_t &value, reader &in) + { + return in.Read(&value, 1) == 1; + } + + static void WriteVarint(uint32_t value, Writer &out) + { + uint8_t b[5] {}; + for (size_t i = 0; i < 5; ++i) { + b[i] = value & 0b0111'1111; + value >>= 7; + if (value) { + b[i] |= 0b1000'0000; + } else { + out.Write(b, i + 1); + break; + } + } + } + + static void WriteVarint(uint64_t value, Writer &out) + { + uint8_t b[10] {}; + for (size_t i = 0; i < 10; ++i) { + b[i] = value & 0b0111'1111; + value >>= 7; + if (value) { + b[i] |= 0b1000'0000; + } else { + out.Write(b, i + 1); + break; + } + } + } + +#if defined(HOST_MAC) + static void WriteVarint(unsigned long value, Writer &out) + { + WriteVarint(static_cast(value), out); + } +#endif + + static bool ReadVarint(uint32_t &value, reader &in) + { + value = 0; + for (size_t c = 0; c < 5; ++c) { + uint8_t x; + if (!ReadByte(x, in)) { + return false; + } + value |= static_cast(x & 0b0111'1111) << 7 * c; + if (!(x & 0b1000'0000)) { + return true; + } + } + + return false; + } + + static bool ReadVarint(uint64_t &value, reader &in) + { + value &= 0; + for (size_t c = 0; c < 10; ++c) { + uint8_t x; + if (!ReadByte(x, in)) { + return false; + } + value |= static_cast(x & 0b0111'1111) << 7 * c; + if (!(x & 0b1000'0000)) { + return true; + } + } + return false; + } + +#if defined(HOST_MAC) + static bool ReadVarint(unsigned long &value, reader &in) + { + uint64_t intermediateValue; + if (ReadVarint(intermediateValue, in)) { + value = static_cast(intermediateValue); + return true; + } + return false; + } +#endif + + static void WriteFixed(uint32_t value, Writer &out) + { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + out.Write(&value, sizeof(value)); +#else + static_assert(false, "Not a little-endian"); +#endif + } + + static void WriteFixed(uint64_t value, Writer &out) + { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + out.Write(&value, sizeof(value)); +#else + static_assert(false, "Not a little-endian"); +#endif + } + + static void WriteFixed(double value, Writer &out) + { + WriteFixed(BitCast(value), out); + } + + static void WriteFixed(float value, Writer &out) + { + WriteFixed(BitCast(value), out); + } + + static void WriteVarint(int32_t value, Writer &out) + { + WriteVarint(BitCast(value), out); + } + + static void WriteVarint(int64_t value, Writer &out) + { + WriteVarint(BitCast(value), out); + } + + static void WriteSignedVarint(int32_t value, Writer &out) + { + WriteVarint(MakeZigzagValue(value), out); + } + + static void WriteSignedVarint(int64_t value, Writer &out) + { + WriteVarint(MakeZigzagValue(value), out); + } + + static void WriteSignedFixed(int32_t value, Writer &out) + { + WriteFixed(static_cast(value), out); + } + + static void WriteSignedFixed(int64_t value, Writer &out) + { + WriteFixed(static_cast(value), out); + } + + static void WriteTagWriteType(uint32_t tag, WireType wireType, Writer &out) + { + WriteVarint(MakeTagWireType(tag, wireType), out); + } + + static bool ReadFixed(uint32_t &value, reader &in) + { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + return in.Read(&value, sizeof(value)) == sizeof(value); +#else + static_assert(false, "Not a little-endian"); +#endif + } + + static bool ReadFixed(uint64_t &value, reader &in) + { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + return in.Read(&value, sizeof(value)) == sizeof(value); +#else + static_assert(false, "Not a little-endian"); +#endif + } + + static bool ReadFixed(double &value, reader &in) + { + uint64_t intermediateValue; + if (ReadFixed(intermediateValue, in)) { + value = BitCast(intermediateValue); + return true; + } + return false; + } + + static bool ReadFixed(float &value, reader &in) + { + uint32_t intermediateValue; + if (ReadFixed(intermediateValue, in)) { + value = BitCast(intermediateValue); + return true; + } + return false; + } + + static bool ReadVarint(int32_t &value, reader &in) + { + uint32_t intermediateValue; + if (ReadVarint(intermediateValue, in)) { + value = BitCast(intermediateValue); + return true; + } + return false; + } + + static bool ReadVarint(int64_t &value, reader &in) + { + uint64_t intermediateValue; + if (ReadVarint(intermediateValue, in)) { + value = BitCast(intermediateValue); + return true; + } + return false; + } + + static bool ReadSignedVarint(int32_t &value, reader &in) + { + uint32_t intermediateValue; + if (ReadVarint(intermediateValue, in)) { + value = ReadZigzagValue(intermediateValue); + return true; + } + return false; + } + + static bool ReadSignedVarint(int64_t &value, reader &in) + { + uint64_t intermediateValue; + if (ReadVarint(intermediateValue, in)) { + value = ReadZigzagValue(intermediateValue); + return true; + } + return false; + } + + static bool ReadSignedFixed(int32_t &value, reader &in) + { + uint32_t intermediateValue; + if (ReadFixed(intermediateValue, in)) { + value = static_cast(intermediateValue); + return true; + } + return false; + } + + static bool ReadSignedFixed(int64_t &value, reader &in) + { + uint64_t intermediateValue; + if (ReadFixed(intermediateValue, in)) { + value = static_cast(intermediateValue); + return true; + } + return false; + } + + template + void WriteField(const T &value, + const SerialDetail::OneofFieldImpl &, Writer &out) + { + using OneOf = SerialDetail::OneofFieldImpl; + Serializer::template SerializeOneof( + OneOf::tag, OneOf::get(value), FlagsType(), out); + } + + template + void WriteField(const T &value, + const SerialDetail::MapFieldImpl &, Writer &out) + { + using Map = SerialDetail::MapFieldImpl; + Serializer::SerializeMap( + Map::tag, Map::get(value), FlagsType(), FlagsType(), out); + } + + template + void WriteField(const T &value, const SerialDetail::FieldImpl &, Writer &out) + { + using Field = SerialDetail::FieldImpl; + Serializer::Serialize( + Field::tag, Field::get(value), FlagsType(), out); + } + + template + void WriteMessage(const T &value, const SerialDetail::MessageImpl &message, Writer &out) + { + message.Visit([&](const auto &field) { WriteField(value, field, out); }); + } + + template + void WriteRepeated(uint32_t tag, It begin, It end, Writer &out) + { + if (begin == end) { + return; + } + if constexpr (SerialDetail::HAS_SERIALIZE_PACKED_V, ValueType, FlagsType, + Writer>) { + WriteVarint(MakeTagWireType(tag, WireType::LENGTH_DELIMETED), out); + WriterSizeCollector sizeCollector; + for (auto it = begin; it != end; ++it) { + Serializer::SerializePacked(*it, FlagsType {}, sizeCollector); + } + WriteVarint(sizeCollector.byte_size, out); + for (auto it = begin; it != end; ++it) { + Serializer::SerializePacked(*it, FlagsType {}, out); + } + } else { + for (auto it = begin; it != end; ++it) { + Serializer::Serialize(tag, *it, FlagsType(), out); + } + } + } + + template + void WriteMapKeyValue(const std::pair &value, Writer &out) + { + Serializer::Serialize(1, value.first, FlagsType {}, out, true); + Serializer::Serialize(2, value.second, FlagsType {}, out, true); + } + + template + void WriteMap(uint32_t tag, const T &value, Writer &out) + { + auto begin = std::begin(value); + auto end = std::end(value); + + for (auto it = begin; it != end; ++it) { + WriteTagWriteType(tag, WireType::LENGTH_DELIMETED, out); + WriterSizeCollector sizeCollector; + WriteMapKeyValue(*it, sizeCollector); + WriteVarint(sizeCollector.byte_size, out); + WriteMapKeyValue(*it, out); + } + } + + template + bool ReadMapKeyValue(std::pair &value, reader &in) + { + static const auto pairAsMessage = Message(Field<1, &std::pair::first, KeyFlags>("key"), + Field<2, &std::pair::second, ValueFlags>("value")); + return ReadMessage(value, pairAsMessage, in); + } + + template + bool ReadMap(WireType wireType, T &value, reader &in) + { + if (wireType != WireType::LENGTH_DELIMETED) { + return false; + } + size_t size; + if (ReadVarint(size, in)) { + LimitedReader limitedIn(in, size); + while (limitedIn.AvailableBytes() > 0) { + std::pair item; + if (!ReadMapKeyValue(item, limitedIn)) { + return false; + } + value.insert(std::move(item)); + } + return true; + } + return false; + } + + template + bool ReadRepeated(WireType wireType, OutputIt output_it, reader &in) + { + if constexpr (SerialDetail::HAS_PARSE_PACKED_V, ValueType, FlagsType, + reader>) { + if (wireType != WireType::LENGTH_DELIMETED) { + return false; + } + + size_t size; + if (ReadVarint(size, in)) { + LimitedReader limitedIn(in, size); + + while (limitedIn.AvailableBytes() > 0) { + ValueType value; + if (!Serializer::ParsePacked(value, FlagsType(), limitedIn)) { + return false; + } + output_it = value; + ++output_it; + } + return true; + } + return false; + } else { + ValueType value; + if (Serializer::Parse(wireType, value, FlagsType(), in)) { + output_it = value; + ++output_it; + return true; + } + return false; + } + } + + template + void ReadField(T &value, uint32_t tag, WireType wireType, + const SerialDetail::OneofFieldImpl &, reader &in) + { + if (Tag != tag) { + return; + } + using OneOf = SerialDetail::OneofFieldImpl; + Serializer::template ParseOneof( + wireType, OneOf::get(value), FlagsType(), in); + } + + template + void ReadField(T &value, uint32_t tag, WireType wireType, + const SerialDetail::MapFieldImpl &, reader &in) + { + if (Tag != tag) { + return; + } + using Map = SerialDetail::MapFieldImpl; + Serializer::ParseMap( + wireType, Map::get(value), FlagsType(), FlagsType(), in); + } + + template + void ReadField(T &value, uint32_t tag, WireType wireType, + const SerialDetail::FieldImpl &, reader &in) + { + if (Tag != tag) { + return; + } + using Field = SerialDetail::FieldImpl; + Serializer::Parse(wireType, Field::get(value), FlagsType(), in); + } + + template bool ReadMessage(T &value, const MessageImpl &message, reader &in) + { + uint32_t tagKey; + while (ReadVarint(tagKey, in)) { + uint32_t tag; + WireType wireType; + ReadTagWireType(tagKey, tag, wireType); + message.Visit([&](const auto &field) { ReadField(value, tag, wireType, field, in); }); + } + return true; + } + } + + template struct Serializer { + // Commion Serializer threat type as Message + static void Serialize(uint32_t tag, const T &value, FlagsType<>, Writer &out, bool force = false) + { + SerialDetail::WriterSizeCollector sizeCollector; + SerialDetail::WriteMessage(value, MessageType(), sizeCollector); + if (!force && sizeCollector.byte_size == 0) { + return; + } + SerialDetail::WriteTagWriteType(tag, WireType::LENGTH_DELIMETED, out); + SerialDetail::WriteVarint(sizeCollector.byte_size, out); + SerialDetail::WriteMessage(value, MessageType(), out); + } + + static bool Parse(WireType wireType, T &value, FlagsType<>, reader &in) + { + if (wireType != WireType::LENGTH_DELIMETED) { + return false; + } + size_t size; + if (SerialDetail::ReadVarint(size, in)) { + SerialDetail::LimitedReader limitedIn(in, size); + return SerialDetail::ReadMessage(value, MessageType(), limitedIn); + } + return false; + } + }; + + template<> struct Serializer { + static void Serialize(uint32_t tag, int32_t value, FlagsType<>, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); + SerialDetail::WriteVarint(value, out); + } + + static void Serialize(uint32_t tag, int32_t value, FlagsType, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); + SerialDetail::WriteSignedVarint(value, out); + } + + static void Serialize( + uint32_t tag, int32_t value, FlagsType, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::FIXED32, out); + SerialDetail::WriteSignedFixed(value, out); + } + + static void SerializePacked(int32_t value, FlagsType<>, Writer &out) + { + SerialDetail::WriteVarint(value, out); + } + + static void SerializePacked(int32_t value, FlagsType, Writer &out) + { + SerialDetail::WriteSignedVarint(value, out); + } + + static void SerializePacked(int32_t value, FlagsType, Writer &out) + { + SerialDetail::WriteSignedFixed(value, out); + } + + static bool Parse(WireType wire_type, int32_t &value, FlagsType<>, reader &in) + { + if (wire_type != WireType::VARINT) + return false; + return SerialDetail::ReadVarint(value, in); + } + + static bool Parse(WireType wire_type, int32_t &value, FlagsType, reader &in) + { + if (wire_type != WireType::VARINT) + return false; + return SerialDetail::ReadSignedVarint(value, in); + } + + static bool Parse(WireType wire_type, int32_t &value, FlagsType, reader &in) + { + if (wire_type != WireType::FIXED32) + return false; + return SerialDetail::ReadSignedFixed(value, in); + } + + static bool ParsePacked(int32_t &value, FlagsType<>, reader &in) + { + return SerialDetail::ReadVarint(value, in); + } + + static bool ParsePacked(int32_t &value, FlagsType, reader &in) + { + return SerialDetail::ReadSignedVarint(value, in); + } + + static bool ParsePacked(int32_t &value, FlagsType, reader &in) + { + return SerialDetail::ReadSignedFixed(value, in); + } + }; + + template<> struct Serializer { + static void Serialize(uint32_t tag, uint32_t value, FlagsType<>, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); + SerialDetail::WriteVarint(value, out); + } + + static void Serialize(uint32_t tag, uint32_t value, FlagsType, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::FIXED32, out); + SerialDetail::WriteFixed(value, out); + } + + static void SerializePacked(uint32_t value, FlagsType<>, Writer &out) + { + SerialDetail::WriteVarint(value, out); + } + + static void SerializePacked(uint32_t value, FlagsType, Writer &out) + { + SerialDetail::WriteFixed(value, out); + } + + static bool Parse(WireType wire_type, uint32_t &value, FlagsType<>, reader &in) + { + if (wire_type != WireType::VARINT) + return false; + return SerialDetail::ReadVarint(value, in); + } + + static bool Parse(WireType wire_type, uint32_t &value, FlagsType, reader &in) + { + if (wire_type != WireType::FIXED32) + return false; + return SerialDetail::ReadFixed(value, in); + } + + static bool ParsePacked(uint32_t &value, FlagsType<>, reader &in) + { + return SerialDetail::ReadVarint(value, in); + } + + static bool ParsePacked(uint32_t &value, FlagsType, reader &in) + { + return SerialDetail::ReadFixed(value, in); + } + }; + + template<> struct Serializer { + static void Serialize(uint32_t tag, int64_t value, FlagsType<>, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); + SerialDetail::WriteVarint(value, out); + } + + static void Serialize(uint32_t tag, int64_t value, FlagsType, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); + SerialDetail::WriteSignedVarint(value, out); + } + + static void Serialize( + uint32_t tag, int64_t value, FlagsType, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::FIXED64, out); + SerialDetail::WriteSignedFixed(value, out); + } + + static void SerializePacked(int64_t value, FlagsType<>, Writer &out) + { + SerialDetail::WriteVarint(value, out); + } + + static void SerializePacked(int64_t value, FlagsType, Writer &out) + { + SerialDetail::WriteSignedVarint(value, out); + } + + static void SerializePacked(int64_t value, FlagsType, Writer &out) + { + SerialDetail::WriteSignedFixed(value, out); + } + + static bool Parse(WireType wire_type, int64_t &value, FlagsType<>, reader &in) + { + if (wire_type != WireType::VARINT) + return false; + return SerialDetail::ReadVarint(value, in); + } + + static bool Parse(WireType wire_type, int64_t &value, FlagsType, reader &in) + { + if (wire_type != WireType::VARINT) + return false; + return SerialDetail::ReadSignedVarint(value, in); + } + + static bool Parse(WireType wire_type, int64_t &value, FlagsType, reader &in) + { + if (wire_type != WireType::FIXED64) + return false; + return SerialDetail::ReadSignedFixed(value, in); + } + + static bool ParsePacked(int64_t &value, FlagsType<>, reader &in) + { + return SerialDetail::ReadVarint(value, in); + } + + static bool ParsePacked(int64_t &value, FlagsType, reader &in) + { + return SerialDetail::ReadSignedVarint(value, in); + } + + static bool ParsePacked(int64_t &value, FlagsType, reader &in) + { + return SerialDetail::ReadSignedFixed(value, in); + } + }; + + template<> struct Serializer { + static void Serialize(uint32_t tag, uint64_t value, FlagsType<>, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); + SerialDetail::WriteVarint(value, out); + } + + static void Serialize(uint32_t tag, uint64_t value, FlagsType, Writer &out, bool force = false) + { + if (!force && value == UINT64_C(0)) + return; + + SerialDetail::WriteTagWriteType(tag, WireType::FIXED64, out); + SerialDetail::WriteFixed(value, out); + } + + static void SerializePacked(uint64_t value, FlagsType<>, Writer &out) + { + SerialDetail::WriteVarint(value, out); + } + + static void SerializePacked(uint64_t value, FlagsType, Writer &out) + { + SerialDetail::WriteFixed(value, out); + } + + static bool Parse(WireType wire_type, uint64_t &value, FlagsType<>, reader &in) + { + if (wire_type != WireType::VARINT) + return false; + return SerialDetail::ReadVarint(value, in); + } + + static bool Parse(WireType wire_type, uint64_t &value, FlagsType, reader &in) + { + if (wire_type != WireType::FIXED64) + return false; + return SerialDetail::ReadFixed(value, in); + } + + static bool ParsePacked(uint64_t &value, FlagsType<>, reader &in) + { + return SerialDetail::ReadVarint(value, in); + } + + static bool ParsePacked(uint64_t &value, FlagsType, reader &in) + { + return SerialDetail::ReadFixed(value, in); + } + }; + + template<> struct Serializer { + static void Serialize(uint32_t tag, double value, FlagsType<>, Writer &out, bool force = false) + { + if (!force && std::fpclassify(value) == FP_ZERO) { + return; + } + SerialDetail::WriteTagWriteType(tag, WireType::FIXED64, out); + SerialDetail::WriteFixed(value, out); + } + + static void SerializePacked(double value, FlagsType<>, Writer &out) + { + SerialDetail::WriteFixed(value, out); + } + + static bool Parse(WireType wire_type, double &value, FlagsType<>, reader &in) + { + if (wire_type != WireType::FIXED64) { + return false; + } + return SerialDetail::ReadFixed(value, in); + } + + static bool ParsePacked(double &value, FlagsType<>, reader &in) + { + return SerialDetail::ReadFixed(value, in); + } + }; + + template<> struct Serializer { + static void Serialize(uint32_t tag, float value, FlagsType<>, Writer &out, bool force = false) + { + if (!force && std::fpclassify(value) == FP_ZERO) { + return; + } + SerialDetail::WriteTagWriteType(tag, WireType::FIXED32, out); + SerialDetail::WriteFixed(value, out); + } + + static void SerializePacked(float value, FlagsType<>, Writer &out) + { + SerialDetail::WriteFixed(value, out); + } + + static bool Parse(WireType wire_type, float &value, FlagsType<>, reader &in) + { + if (wire_type != WireType::FIXED32) { + return false; + } + return SerialDetail::ReadFixed(value, in); + } + + static bool ParsePacked(float &value, FlagsType<>, reader &in) + { + return SerialDetail::ReadFixed(value, in); + } + }; + + template<> struct Serializer { + static void Serialize(uint32_t tag, bool value, FlagsType<>, Writer &out, bool force = false) + { + Serializer::Serialize(tag, value ? 1 : 0, FlagsType(), out, force); + } + + static void SerializePacked(bool value, FlagsType<>, Writer &out) + { + Serializer::SerializePacked(value ? 1 : 0, FlagsType(), out); + } + + static bool Parse(WireType wire_type, bool &value, FlagsType<>, reader &in) + { + uint32_t intermedaite_value; + if (Serializer::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) { + value = static_cast(intermedaite_value); + return true; + } + return false; + } + + static bool ParsePacked(bool &value, FlagsType<>, reader &in) + { + uint32_t intermedaite_value; + if (Serializer::ParsePacked(intermedaite_value, FlagsType<>(), in)) { + value = static_cast(intermedaite_value); + return true; + } + return false; + } + }; + + template struct Serializer>> { + using U = std::underlying_type_t; + + static void Serialize(uint32_t tag, T value, FlagsType<>, Writer &out, bool force = false) + { + Serializer::Serialize(tag, static_cast(value), FlagsType<>(), out, force); + } + + static void SerializePacked(T value, FlagsType<>, Writer &out) + { + Serializer::SerializePacked(static_cast(value), FlagsType<>(), out); + } + + static bool Parse(WireType wire_type, T &value, FlagsType<>, reader &in) + { + U intermedaite_value; + if (Serializer::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) { + value = static_cast(intermedaite_value); + return true; + } + return false; + } + + static bool ParsePacked(T &value, FlagsType<>, reader &in) + { + U intermedaite_value; + if (Serializer::ParsePacked(intermedaite_value, FlagsType<>(), in)) { + value = static_cast(intermedaite_value); + return true; + } + return false; + } + }; + + template<> struct Serializer { + static void Serialize(uint32_t tag, const std::string &value, FlagsType<>, Writer &out, bool force = false) + { + SerialDetail::WriteTagWriteType(tag, WireType::LENGTH_DELIMETED, out); + SerialDetail::WriteVarint(value.size(), out); + out.Write(value.data(), value.size()); + } + + static bool Parse(WireType wire_type, std::string &value, FlagsType<>, reader &in) + { + if (wire_type != WireType::LENGTH_DELIMETED) { + return false; + } + size_t size; + if (SerialDetail::ReadVarint(size, in)) { + value.resize(size); + if (in.Read(value.data(), size) == size) { + return true; + } + } + return false; + } + }; + + template struct Serializer> { + template + static void Serialize(uint32_t tag, const std::vector &value, FlagsType, Writer &out) + { + SerialDetail::WriteRepeated(tag, value.begin(), value.end(), out); + } + + template + static bool Parse(WireType wire_type, std::vector &value, FlagsType, reader &in) + { + return SerialDetail::ReadRepeated(wire_type, std::back_inserter(value), in); + } + }; + + template struct Serializer> { + template + static void Serialize(uint32_t tag, const std::optional &value, FlagsType, Writer &out) + { + if (!value.has_value()) { + return; + } + Serializer::Serialize(tag, *value, FlagsType(), out); + } + + template + static bool Parse(WireType wire_type, std::optional &value, FlagsType, reader &in) + { + return Serializer::Parse(wire_type, value.emplace(), FlagsType(), in); + } + }; + + template struct Serializer> { + template + static void SerializeOneof(uint32_t tag, const std::variant &value, FlagsType, Writer &out) + { + if (value.index() != Index) + return; + + Serializer>>::Serialize( + tag, std::get(value), FlagsType(), out); + } + + template + static bool ParseOneof(WireType wire_type, std::variant &value, FlagsType, reader &in) + { + return Serializer>>::Parse( + wire_type, value.template emplace(), FlagsType(), in); + } + }; + + template struct Serializer> { + template + static void SerializeMap( + uint32_t tag, const std::map &value, FlagsType, FlagsType, Writer &out) + { + SerialDetail::WriteMap(tag, value, out); + } + + template + static bool ParseMap( + WireType wire_type, std::map &value, FlagsType, FlagsType, reader &in) + { + return SerialDetail::ReadMap(wire_type, value, in); + } + }; + + struct StringWriter : public Writer { + StringWriter(std::string &out) + : _out(out) + { + } + + void Write(const void *bytes, size_t size) override + { + _out.append(reinterpret_cast(bytes), size); + } + + private: + std::string &_out; + }; + + struct StringReader : public reader { + StringReader(const std::string &in) + : _in(in), _pos(0) + { + } + + size_t Read(void *bytes, size_t size) override + { + size_t readSize = std::min(size, _in.size() - _pos); + if (memcpy_s(bytes, size, _in.data() + _pos, readSize) != EOK) { + return readSize; + } + _pos += readSize; + return readSize; + } + + private: + const std::string &_in; + size_t _pos; + }; + // mytype begin, just support base type, but really use protobuf raw type(uint32) + template<> struct Serializer { + static void Serialize(uint32_t tag, uint8_t value, FlagsType<>, Writer &out, bool force = false) + { + Serializer::Serialize(tag, value, FlagsType(), out, force); + } + + static void SerializePacked(uint8_t value, FlagsType<>, Writer &out) + { + Serializer::SerializePacked(value, FlagsType(), out); + } + + static bool Parse(WireType wire_type, uint8_t &value, FlagsType<>, reader &in) + { + uint32_t intermedaite_value; + if (Serializer::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) { + value = static_cast(intermedaite_value); + return true; + } + return false; + } + + static bool ParsePacked(uint8_t &value, FlagsType<>, reader &in) + { + uint32_t intermedaite_value; + if (Serializer::ParsePacked(intermedaite_value, FlagsType<>(), in)) { + value = static_cast(intermedaite_value); + return true; + } + return false; + } + }; + template<> struct Serializer { + static void Serialize(uint32_t tag, uint16_t value, FlagsType<>, Writer &out, bool force = false) + { + Serializer::Serialize(tag, value, FlagsType(), out, force); + } + + static void SerializePacked(uint16_t value, FlagsType<>, Writer &out) + { + Serializer::SerializePacked(value, FlagsType(), out); + } + + static bool Parse(WireType wire_type, uint16_t &value, FlagsType<>, reader &in) + { + uint32_t intermedaite_value; + if (Serializer::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) { + value = static_cast(intermedaite_value); + return true; + } + return false; + } + + static bool ParsePacked(uint16_t &value, FlagsType<>, reader &in) + { + uint32_t intermedaite_value; + if (Serializer::ParsePacked(intermedaite_value, FlagsType<>(), in)) { + value = static_cast(intermedaite_value); + return true; + } + return false; + } + }; + // mytype finish + + template std::string SerializeToString(const T &value) + { + std::string out; + StringWriter stringOut(out); + SerialDetail::WriteMessage(value, MessageType(), stringOut); + return out; + } + + template bool ParseFromString(T &value, const std::string &in) + { + StringReader stringIn(in); + return SerialDetail::ReadMessage(value, MessageType(), stringIn); + } +} +// clang-format on +} // Hdc +#endif // HDC_SERIAL_STRUCT_DEFINE_H diff --git a/services/flashd/common/session.cpp b/services/flashd/common/session.cpp new file mode 100755 index 00000000..bef648a2 --- /dev/null +++ b/services/flashd/common/session.cpp @@ -0,0 +1,1062 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "session.h" +#include "serial_struct.h" + +namespace Hdc { +HdcSessionBase::HdcSessionBase(bool serverOrDaemonIn) +{ + // server/daemon common initialization code + string threadNum = std::to_string(SIZE_THREAD_POOL); + uv_os_setenv("UV_THREADPOOL_SIZE", threadNum.c_str()); + uv_loop_init(&loopMain); + WRITE_LOG(LOG_DEBUG, "loopMain init"); + uv_rwlock_init(&mainAsync); + uv_async_init(&loopMain, &asyncMainLoop, MainAsyncCallback); + uv_rwlock_init(&lockMapSession); + serverOrDaemon = serverOrDaemonIn; + ctxUSB = nullptr; + wantRestart = false; + +#ifdef HDC_HOST + if (serverOrDaemon) { + libusb_init((libusb_context **)&ctxUSB); + } +#endif +} + +HdcSessionBase::~HdcSessionBase() +{ + Base::TryCloseHandle((uv_handle_t *)&asyncMainLoop); + uv_loop_close(&loopMain); + // clear base + uv_rwlock_destroy(&mainAsync); + uv_rwlock_destroy(&lockMapSession); +#ifdef HDC_HOST + if (serverOrDaemon) { + libusb_exit((libusb_context *)ctxUSB); + } +#endif + WRITE_LOG(LOG_DEBUG, "~HdcSessionBase free sessionRef:%d instance:%s", uint32_t(sessionRef), + serverOrDaemon ? "server" : "daemon"); +} + +// remove step2 +bool HdcSessionBase::TryRemoveTask(HTaskInfo hTask) +{ + if (hTask->taskFree) { + return true; + } + bool ret = RemoveInstanceTask(OP_REMOVE, hTask); + if (ret) { + hTask->taskFree = true; + } else { + // This is used to check that the memory cannot be cleaned up. If the memory cannot be released, break point + // here to see which task has not been released + // print task clear + } + return ret; +} + +// remove step1 +bool HdcSessionBase::BeginRemoveTask(HTaskInfo hTask) +{ + bool ret = true; + if (hTask->taskStop || hTask->taskFree || !hTask->taskClass) { + return true; + } + + WRITE_LOG(LOG_DEBUG, "BeginRemoveTask taskType:%d", hTask->taskType); + ret = RemoveInstanceTask(OP_CLEAR, hTask); + auto taskClassDeleteRetry = [](uv_idle_t *handle) -> void { + HTaskInfo hTask = (HTaskInfo)handle->data; + HdcSessionBase *thisClass = (HdcSessionBase *)hTask->ownerSessionClass; + if (!thisClass->TryRemoveTask(hTask)) { + return; + } + HSession hSession = thisClass->AdminSession(OP_QUERY, hTask->sessionId, nullptr); + thisClass->AdminTask(OP_REMOVE, hSession, hTask->channelId, nullptr); + WRITE_LOG(LOG_DEBUG, "TaskDelay task remove finish, channelId:%d", hTask->channelId); + delete hTask; + Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseIdleCallback); + }; + Base::IdleUvTask(hTask->runLoop, hTask, taskClassDeleteRetry); + + hTask->taskStop = true; + ret = true; + return ret; +} + +// Clear all Task or a single Task, the regular situation is stopped first, and the specific class memory is cleaned up +// after the end of the LOOP. +// When ChannelIdinput == 0, at this time, all of the LOOP ends, all runs in the class end, so directly skip STOP, +// physical memory deletion class trimming +void HdcSessionBase::ClearOwnTasks(HSession hSession, const uint32_t channelIDInput) +{ + // First case: normal task cleanup process (STOP Remove) + // Second: The task is cleaned up, the session ends + // Third: The task is cleaned up, and the session is directly over the session. + map::iterator iter; + for (iter = hSession->mapTask->begin(); iter != hSession->mapTask->end();) { + uint32_t channelId = iter->first; + HTaskInfo hTask = iter->second; + if (channelIDInput != 0) { // single + if (channelIDInput != channelId) { + ++iter; + continue; + } + BeginRemoveTask(hTask); + WRITE_LOG(LOG_DEBUG, "ClearOwnTasks OP_CLEAR finish,session:%p channelIDInput:%d", hSession, + channelIDInput); + break; + } + // multi + BeginRemoveTask(hTask); + ++iter; + } +} + +void HdcSessionBase::ClearSessions() +{ + // no need to lock mapSession + // broadcast free singal + for (auto v : mapSession) { + HSession hSession = (HSession)v.second; + if (!hSession->isDead) { + FreeSession(hSession->sessionId); + } + } +} + +void HdcSessionBase::ReMainLoopForInstanceClear() +{ // reloop + auto clearSessionsForFinish = [](uv_idle_t *handle) -> void { + HdcSessionBase *thisClass = (HdcSessionBase *)handle->data; + if (thisClass->sessionRef > 0) { + return; + } + // all task has been free + uv_close((uv_handle_t *)handle, Base::CloseIdleCallback); + uv_stop(&thisClass->loopMain); + }; + Base::IdleUvTask(&loopMain, this, clearSessionsForFinish); + uv_run(&loopMain, UV_RUN_DEFAULT); +}; + +void HdcSessionBase::EnumUSBDeviceRegister(void (*pCallBack)(HSession hSession)) +{ + if (!pCallBack) { + return; + } + uv_rwlock_rdlock(&lockMapSession); + map::iterator i; + for (i = mapSession.begin(); i != mapSession.end(); ++i) { + HSession hs = i->second; + if (hs->connType != CONN_USB) { + continue; + } + if (hs->hUSB == nullptr) { + continue; + } + if (pCallBack) { + pCallBack(hs); + } + break; + } + uv_rwlock_rdunlock(&lockMapSession); +} + +// The PC side gives the device information, determines if the USB device is registered +// PDEV and Busid Devid two choices +HSession HdcSessionBase::QueryUSBDeviceRegister(void *pDev, int busIDIn, int devIDIn) +{ +#ifdef HDC_HOST + libusb_device *dev = (libusb_device *)pDev; + HSession hResult = nullptr; + if (!mapSession.size()) { + return nullptr; + } + uint8_t busId = 0; + uint8_t devId = 0; + if (pDev) { + busId = libusb_get_bus_number(dev); + devId = libusb_get_device_address(dev); + } else { + busId = busIDIn; + devId = devIDIn; + } + uv_rwlock_rdlock(&lockMapSession); + map::iterator i; + for (i = mapSession.begin(); i != mapSession.end(); ++i) { + HSession hs = i->second; + if (hs->connType == CONN_USB) { + continue; + } + if (hs->hUSB == nullptr) { + continue; + } + if (hs->hUSB->devId != devId || hs->hUSB->busId != busId) { + continue; + } + hResult = hs; + break; + } + uv_rwlock_rdunlock(&lockMapSession); + return hResult; +#else + return nullptr; +#endif +} + +void HdcSessionBase::AsyncMainLoopTask(uv_idle_t *handle) +{ + AsyncParam *param = (AsyncParam *)handle->data; + HdcSessionBase *thisClass = (HdcSessionBase *)param->thisClass; + switch (param->method) { + case ASYNC_FREE_SESSION: + // Destruction is unified in the main thread + thisClass->FreeSession(param->sid); // todo Double lock + break; + case ASYNC_STOP_MAINLOOP: + uv_stop(&thisClass->loopMain); + break; + default: + break; + } + if (param->data) { + delete[]((uint8_t *)param->data); + } + delete param; + param = nullptr; + Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseIdleCallback); +} + +void HdcSessionBase::MainAsyncCallback(uv_async_t *handle) +{ + HdcSessionBase *thisClass = (HdcSessionBase *)handle->data; + list::iterator i; + list &lst = thisClass->lstMainThreadOP; + uv_rwlock_wrlock(&thisClass->mainAsync); + for (i = lst.begin(); i != lst.end();) { + AsyncParam *param = (AsyncParam *)*i; + Base::IdleUvTask(&thisClass->loopMain, param, AsyncMainLoopTask); + i = lst.erase(i); + } + uv_rwlock_wrunlock(&thisClass->mainAsync); +} + +void HdcSessionBase::PushAsyncMessage(const uint32_t sessionId, const uint8_t method, const void *data, + const int dataSize) +{ + AsyncParam *param = new AsyncParam(); + if (!param) { + return; + } + param->sid = sessionId; + param->thisClass = this; + param->method = method; + if (dataSize > 0) { + param->dataSize = dataSize; + param->data = new uint8_t[param->dataSize](); + if (!param->data) { + delete param; + return; + } + if (memcpy_s((uint8_t *)param->data, param->dataSize, data, dataSize)) { + delete[]((uint8_t *)param->data); + delete param; + return; + } + } + + asyncMainLoop.data = this; + uv_rwlock_wrlock(&mainAsync); + lstMainThreadOP.push_back(param); + uv_rwlock_wrunlock(&mainAsync); + uv_async_send(&asyncMainLoop); +} + +void HdcSessionBase::WorkerPendding() +{ + uv_run(&loopMain, UV_RUN_DEFAULT); + ClearInstanceResource(); +} + +int HdcSessionBase::MallocSessionByConnectType(HSession hSession) +{ + int ret = 0; + switch (hSession->connType) { + case CONN_TCP: { + uv_tcp_init(&loopMain, &hSession->hWorkTCP); + ++hSession->uvRef; + hSession->hWorkTCP.data = hSession; + break; + } + case CONN_USB: { + // Some members need to be placed at the primary thread + HUSB hUSB = new HdcUSB(); + if (!hUSB) { + ret = -1; + break; + } + hSession->hUSB = hUSB; +#ifdef HDC_HOST + constexpr auto maxBufFactor = 1.5; + int max = Base::GetMaxBufSize() * maxBufFactor + sizeof(USBHead); + hUSB->sizeEpBuf = max; + hUSB->bufDevice = new uint8_t[max](); + hUSB->bufHost = new uint8_t[max](); + hUSB->transferRecv = libusb_alloc_transfer(0); + hUSB->transferSend = libusb_alloc_transfer(0); +#else +#endif + break; + } + default: + ret = -1; + break; + } + return ret; +} + +// Avoid unit test when client\server\daemon on the same host, maybe get the same ID value +uint32_t HdcSessionBase::GetSessionPseudoUid() +{ + uint32_t uid = 0; + Hdc::HSession hInput = nullptr; + do { + uid = static_cast(Base::GetRandom()); + } while ((hInput = AdminSession(OP_QUERY, uid, nullptr)) != nullptr); + return uid; +} + +// when client 0 to automatic generated,when daemon First place 1 followed by +HSession HdcSessionBase::MallocSession(bool serverOrDaemon, const ConnType connType, void *classModule, + uint32_t sessionId) +{ + HSession hSession = new HdcSession(); + if (!hSession) { + return nullptr; + } + int ret = 0; + ++sessionRef; + memset_s(hSession->ctrlFd, sizeof(hSession->ctrlFd), 0, sizeof(hSession->ctrlFd)); + hSession->classInstance = this; + hSession->connType = connType; + hSession->classModule = classModule; + hSession->isDead = false; + hSession->sessionId = ((sessionId == 0) ? GetSessionPseudoUid() : sessionId); + hSession->serverOrDaemon = serverOrDaemon; + hSession->hWorkThread = uv_thread_self(); + hSession->mapTask = new map(); + hSession->listKey = new list; + hSession->uvRef = 0; + // pullup child + WRITE_LOG(LOG_DEBUG, "HdcSessionBase NewSession, sessionId:%u", hSession->sessionId); + + uv_tcp_init(&loopMain, &hSession->ctrlPipe[STREAM_MAIN]); + ++hSession->uvRef; + Base::CreateSocketPair(hSession->ctrlFd); + uv_tcp_open(&hSession->ctrlPipe[STREAM_MAIN], hSession->ctrlFd[STREAM_MAIN]); + uv_read_start((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], Base::AllocBufferCallback, ReadCtrlFromSession); + hSession->ctrlPipe[STREAM_MAIN].data = hSession; + hSession->ctrlPipe[STREAM_WORK].data = hSession; + // Activate USB DAEMON's data channel, may not for use + uv_tcp_init(&loopMain, &hSession->dataPipe[STREAM_MAIN]); + ++hSession->uvRef; + Base::CreateSocketPair(hSession->dataFd); + uv_tcp_open(&hSession->dataPipe[STREAM_MAIN], hSession->dataFd[STREAM_MAIN]); + hSession->dataPipe[STREAM_MAIN].data = hSession; + hSession->dataPipe[STREAM_WORK].data = hSession; + Base::SetTcpOptions(&hSession->dataPipe[STREAM_MAIN]); + ret = MallocSessionByConnectType(hSession); + if (ret) { + delete hSession; + hSession = nullptr; + } else { + AdminSession(OP_ADD, hSession->sessionId, hSession); + } + return hSession; +} + +void HdcSessionBase::FreeSessionByConnectType(HSession hSession) +{ + if (CONN_USB == hSession->connType) { + // ibusb All context is applied for sub-threaded, so it needs to be destroyed in the subline + if (!hSession->hUSB) { + return; + } + HUSB hUSB = hSession->hUSB; + if (!hUSB) { + return; + } +#ifdef HDC_HOST + if (hUSB->devHandle) { + libusb_release_interface(hUSB->devHandle, hUSB->interfaceNumber); + libusb_close(hUSB->devHandle); + hUSB->devHandle = nullptr; + } + + delete[] hUSB->bufDevice; + delete[] hUSB->bufHost; + libusb_free_transfer(hUSB->transferRecv); + libusb_free_transfer(hUSB->transferSend); +#else + if (hUSB->bulkIn > 0) { + close(hUSB->bulkIn); + hUSB->bulkIn = 0; + } + if (hUSB->bulkOut > 0) { + close(hUSB->bulkOut); + hUSB->bulkOut = 0; + } +#endif + delete hSession->hUSB; + hSession->hUSB = nullptr; + } +} + +// work when libuv-handle at struct of HdcSession has all callback finished +void HdcSessionBase::FreeSessionFinally(uv_idle_t *handle) +{ + HSession hSession = (HSession)handle->data; + HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; + if (hSession->uvRef > 0) { + return; + } + // Notify Server or Daemon, just UI or display commandline + thisClass->NotifyInstanceSessionFree(hSession, true); + // all hsession uv handle has been clear + thisClass->AdminSession(OP_REMOVE, hSession->sessionId, nullptr); + WRITE_LOG(LOG_DEBUG, "!!!FreeSessionFinally sessionId:%u finish", hSession->sessionId); + delete hSession; + hSession = nullptr; // fix CodeMars SetNullAfterFree issue + Base::TryCloseHandle((const uv_handle_t *)handle, Base::CloseIdleCallback); + --thisClass->sessionRef; +} + +// work when child-work thread finish +void HdcSessionBase::FreeSessionContinue(HSession hSession) +{ + auto closeSessionTCPHandle = [](uv_handle_t *handle) -> void { + HSession hSession = (HSession)handle->data; + --hSession->uvRef; + Base::TryCloseHandle((uv_handle_t *)handle); + }; + if (CONN_TCP == hSession->connType) { + // Turn off TCP to prevent continuing writing + Base::TryCloseHandle((uv_handle_t *)&hSession->hWorkTCP, true, closeSessionTCPHandle); + } + hSession->availTailIndex = 0; + if (hSession->ioBuf) { + delete[] hSession->ioBuf; + hSession->ioBuf = nullptr; + } + Base::TryCloseHandle((uv_handle_t *)&hSession->ctrlPipe[STREAM_MAIN], true, closeSessionTCPHandle); + Base::TryCloseHandle((uv_handle_t *)&hSession->dataPipe[STREAM_MAIN], true, closeSessionTCPHandle); + delete hSession->mapTask; + HdcAuth::FreeKey(!hSession->serverOrDaemon, hSession->listKey); + delete hSession->listKey; // to clear + FreeSessionByConnectType(hSession); + // finish + Base::IdleUvTask(&loopMain, hSession, FreeSessionFinally); +} + +void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) +{ + HSession hSession = (HSession)handle->data; + HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; + if (hSession->sendRef > 0) { + return; + } +#ifdef HDC_HOST + if (hSession->hUSB != nullptr && (!hSession->hUSB->recvIOComplete || !hSession->hUSB->sendIOComplete)) { + return; + } +#endif + // wait workthread to free + if (hSession->ctrlPipe[STREAM_WORK].loop) { + auto ctrl = BuildCtrlString(SP_STOP_SESSION, 0, nullptr, 0); + Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); + WRITE_LOG(LOG_DEBUG, "FreeSession, send workthread fo free. sessionId:%u", hSession->sessionId); + auto callbackCheckFreeSessionContinue = [](uv_timer_t *handle) -> void { + HSession hSession = (HSession)handle->data; + HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; + if (!hSession->childCleared) { + return; + } + Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseTimerCallback); + thisClass->FreeSessionContinue(hSession); + }; + Base::TimerUvTask(&thisClass->loopMain, hSession, callbackCheckFreeSessionContinue); + } else { + thisClass->FreeSessionContinue(hSession); + } + Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseTimerCallback); +} + +void HdcSessionBase::FreeSession(const uint32_t sessionId) +{ + HSession hSession = AdminSession(OP_QUERY, sessionId, nullptr); + if (!hSession) { + return; + } + if (hSession->hWorkThread != uv_thread_self()) { + PushAsyncMessage(hSession->sessionId, ASYNC_FREE_SESSION, nullptr, 0); + return; + } + if (hSession->isDead) { + return; + } + hSession->isDead = true; + Base::TimerUvTask(&loopMain, hSession, FreeSessionOpeate); + NotifyInstanceSessionFree(hSession, false); + WRITE_LOG(LOG_DEBUG, "FreeSession sessionId:%u sendref:%u", hSession->sessionId, uint16_t(hSession->sendRef)); +} + +HSession HdcSessionBase::AdminSession(const uint8_t op, const uint32_t sessionId, HSession hInput) +{ + HSession hRet = nullptr; + switch (op) { + case OP_ADD: + uv_rwlock_wrlock(&lockMapSession); + mapSession[sessionId] = hInput; + uv_rwlock_wrunlock(&lockMapSession); + break; + case OP_REMOVE: + uv_rwlock_wrlock(&lockMapSession); + mapSession.erase(sessionId); + uv_rwlock_wrunlock(&lockMapSession); + break; + case OP_QUERY: + uv_rwlock_rdlock(&lockMapSession); + if (mapSession.count(sessionId)) { + hRet = mapSession[sessionId]; + } + uv_rwlock_rdunlock(&lockMapSession); + break; + case OP_UPDATE: + uv_rwlock_wrlock(&lockMapSession); + // remove old + mapSession.erase(sessionId); + mapSession[hInput->sessionId] = hInput; + uv_rwlock_wrunlock(&lockMapSession); + break; + default: + break; + } + return hRet; +} + +// All in the corresponding sub-thread, no need locks +HTaskInfo HdcSessionBase::AdminTask(const uint8_t op, HSession hSession, const uint32_t channelId, HTaskInfo hInput) +{ + HTaskInfo hRet = nullptr; + map &mapTask = *hSession->mapTask; + switch (op) { + case OP_ADD: + mapTask[channelId] = hInput; + break; + case OP_REMOVE: + mapTask.erase(channelId); + break; + case OP_QUERY: + if (mapTask.count(channelId)) { + hRet = mapTask[channelId]; + } + break; + default: + break; + } + return hRet; +} + +int HdcSessionBase::SendByProtocol(HSession hSession, uint8_t *bufPtr, const int bufLen) +{ + if (hSession->isDead) { + return ERR_SESSION_NOFOUND; + } + int ret = 0; + ++hSession->sendRef; + switch (hSession->connType) { + case CONN_TCP: { + if (hSession->hWorkThread == uv_thread_self()) { + ret = Base::SendToStreamEx((uv_stream_t *)&hSession->hWorkTCP, bufPtr, bufLen, nullptr, + (void *)FinishWriteSessionTCP, bufPtr); + } else if (hSession->hWorkChildThread == uv_thread_self()) { + ret = Base::SendToStreamEx((uv_stream_t *)&hSession->hChildWorkTCP, bufPtr, bufLen, nullptr, + (void *)FinishWriteSessionTCP, bufPtr); + } else { + WRITE_LOG(LOG_FATAL, "SendByProtocol uncontrol send"); + ret = ERR_API_FAIL; + } + break; + } + case CONN_USB: { + HdcUSBBase *pUSB = ((HdcUSBBase *)hSession->classModule); + ret = pUSB->SendUSBBlock(hSession, bufPtr, bufLen); + delete[] bufPtr; + break; + } + default: + break; + } + return ret; +} + +int HdcSessionBase::Send(const uint32_t sessionId, const uint32_t channelId, const uint16_t commandFlag, + const uint8_t *data, const int dataSize) +{ + HSession hSession = AdminSession(OP_QUERY, sessionId, nullptr); + if (!hSession) { + WRITE_LOG(LOG_DEBUG, "Send to offline device, drop it, sessionId:%u", sessionId); + return ERR_SESSION_NOFOUND; + } + PayloadProtect protectBuf; // noneed convert to big-endian + protectBuf.channelId = channelId; + protectBuf.commandFlag = commandFlag; + protectBuf.checkSum = (ENABLE_IO_CHECKSUM && dataSize > 0) ? Base::CalcCheckSum(data, dataSize) : 0; + protectBuf.vCode = payloadProtectStaticVcode; + string s = SerialStruct::SerializeToString(protectBuf); + // reserve for encrypt here + // xx-encrypt + + PayloadHead payloadHead; // need convert to big-endian + Base::ZeroStruct(payloadHead); + payloadHead.flag[0] = PACKET_FLAG.at(0); + payloadHead.flag[1] = PACKET_FLAG.at(1); + payloadHead.protocolVer = VER_PROTOCOL; + payloadHead.headSize = htons(s.size()); + payloadHead.dataSize = htonl(dataSize); + int finalBufSize = sizeof(PayloadHead) + s.size() + dataSize; + uint8_t *finayBuf = new uint8_t[finalBufSize](); + if (finayBuf == nullptr) { + return ERR_BUF_ALLOC; + } + bool bufRet = false; + do { + if (memcpy_s(finayBuf, sizeof(PayloadHead), reinterpret_cast(&payloadHead), sizeof(PayloadHead))) { + break; + } + if (memcpy_s(finayBuf + sizeof(PayloadHead), s.size(), + reinterpret_cast(const_cast(s.c_str())), s.size())) { + break; + } + if (dataSize > 0 && memcpy_s(finayBuf + sizeof(PayloadHead) + s.size(), dataSize, data, dataSize)) { + break; + } + bufRet = true; + } while (false); + if (!bufRet) { + delete[] finayBuf; + return ERR_BUF_COPY; + } + return SendByProtocol(hSession, finayBuf, finalBufSize); +} + +int HdcSessionBase::DecryptPayload(HSession hSession, PayloadHead *payloadHeadBe, uint8_t *encBuf) +{ + PayloadProtect protectBuf; + Base::ZeroStruct(protectBuf); + uint16_t headSize = ntohs(payloadHeadBe->headSize); + int dataSize = ntohl(payloadHeadBe->dataSize); + string encString(reinterpret_cast(encBuf), headSize); + SerialStruct::ParseFromString(protectBuf, encString); + if (protectBuf.vCode != payloadProtectStaticVcode) { + WRITE_LOG(LOG_FATAL, "Session recv static vcode failed"); + return ERR_BUF_CHECK; + } + uint8_t *data = encBuf + headSize; + if (protectBuf.checkSum != 0 && (protectBuf.checkSum != Base::CalcCheckSum(data, dataSize))) { + WRITE_LOG(LOG_FATAL, "Session recv CalcCheckSum failed"); + return ERR_BUF_CHECK; + } + if (!FetchCommand(hSession, protectBuf.channelId, protectBuf.commandFlag, data, dataSize)) { + WRITE_LOG(LOG_WARN, "FetchCommand failed"); + return ERR_GENERIC; + } + return RET_SUCCESS; +} + +int HdcSessionBase::OnRead(HSession hSession, uint8_t *bufPtr, const int bufLen) +{ + int ret = ERR_GENERIC; + if (memcmp(bufPtr, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { + return ERR_BUF_CHECK; + } + struct PayloadHead *payloadHead = (struct PayloadHead *)bufPtr; + int tobeReadLen = ntohl(payloadHead->dataSize) + ntohs(payloadHead->headSize); + int packetHeadSize = sizeof(struct PayloadHead); + if (tobeReadLen <= 0 || (uint32_t)tobeReadLen > HDC_BUF_MAX_BYTES) { + // max 1G + return ERR_BUF_CHECK; + } + if (bufLen - packetHeadSize < tobeReadLen) { + return 0; + } + if (DecryptPayload(hSession, payloadHead, bufPtr + packetHeadSize)) { + return ERR_BUF_CHECK; + } + ret = packetHeadSize + tobeReadLen; + return ret; +} + +// Returns <0 error;> 0 receives the number of bytes; 0 untreated +int HdcSessionBase::FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read) +{ + HdcSessionBase *ptrConnect = (HdcSessionBase *)hSession->classInstance; + int indexBuf = 0; + int childRet = 0; + if (read < 0) { + return ERR_IO_FAIL; + } + hSession->availTailIndex += read; + while (!hSession->isDead && hSession->availTailIndex > static_cast(sizeof(PayloadHead))) { + childRet = ptrConnect->OnRead(hSession, ioBuf + indexBuf, hSession->availTailIndex); + if (childRet > 0) { + hSession->availTailIndex -= childRet; + indexBuf += childRet; + } else if (childRet == 0) { + // Not enough a IO + break; + } else { + // <0 + hSession->availTailIndex = 0; // Preventing malicious data packages + indexBuf = ERR_BUF_SIZE; + break; + } + // It may be multi-time IO to merge in a BUF, need to loop processing + } + if (indexBuf > 0 && hSession->availTailIndex > 0) { + memmove_s(hSession->ioBuf, hSession->bufSize, hSession->ioBuf + indexBuf, hSession->availTailIndex); + uint8_t *bufToZero = (uint8_t *)(hSession->ioBuf + hSession->availTailIndex); + Base::ZeroBuf(bufToZero, hSession->bufSize - hSession->availTailIndex); + } + return indexBuf; +} + +void HdcSessionBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) +{ + HSession context = (HSession)handle->data; + Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); + buf->base = (char *)context->ioBuf + context->availTailIndex; + buf->len = context->bufSize - context->availTailIndex - 1; // 16Bytes are retained to prevent memory sticking + assert(buf->len >= 0); +} + +void HdcSessionBase::FinishWriteSessionTCP(uv_write_t *req, int status) +{ + HSession hSession = (HSession)req->handle->data; + --hSession->sendRef; + HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; + if (status < 0) { + Base::TryCloseHandle((uv_handle_t *)req->handle); + if (!hSession->isDead && !hSession->sendRef) { + WRITE_LOG(LOG_DEBUG, "FinishWriteSessionTCP freesession :%p", hSession); + thisClass->FreeSession(hSession->sessionId); + } + } + delete[]((uint8_t *)req->data); + delete req; +} + +bool HdcSessionBase::DispatchSessionThreadCommand(uv_stream_t *uvpipe, HSession hSession, const uint8_t *baseBuf, + const int bytesIO) +{ + bool ret = true; + uint8_t flag = *(uint8_t *)baseBuf; + + switch (flag) { + case SP_JDWP_NEWFD: { + JdwpNewFileDescriptor(baseBuf, bytesIO); + break; + } + default: + WRITE_LOG(LOG_WARN, "Not support session command"); + break; + } + return ret; +} + +void HdcSessionBase::ReadCtrlFromSession(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf) +{ + HSession hSession = (HSession)uvpipe->data; + HdcSessionBase *hSessionBase = (HdcSessionBase *)hSession->classInstance; + while (true) { + if (nread < 0) { + WRITE_LOG(LOG_DEBUG, "SessionCtrl failed,%s", uv_strerror(nread)); + break; + } + if (nread > 64) { // 64 : max length + WRITE_LOG(LOG_WARN, "HdcSessionBase read overlap data"); + break; + } + // only one command, no need to split command from stream + // if add more commands, consider the format command + hSessionBase->DispatchSessionThreadCommand(uvpipe, hSession, (uint8_t *)buf->base, nread); + break; + } + delete[] buf->base; +} + +bool HdcSessionBase::WorkThreadStartSession(HSession hSession) +{ + bool regOK = false; + int childRet = 0; + if (hSession->connType == CONN_TCP) { + HdcTCPBase *pTCPBase = (HdcTCPBase *)hSession->classModule; + hSession->hChildWorkTCP.data = hSession; + if ((childRet = uv_tcp_init(&hSession->childLoop, &hSession->hChildWorkTCP)) < 0) { + WRITE_LOG(LOG_DEBUG, "HdcSessionBase SessionCtrl failed 1"); + return false; + } + if ((childRet = uv_tcp_open(&hSession->hChildWorkTCP, hSession->fdChildWorkTCP)) < 0) { + WRITE_LOG(LOG_DEBUG, "SessionCtrl failed 2,fd:%d,str:%s", hSession->fdChildWorkTCP, uv_strerror(childRet)); + return false; + } + Base::SetTcpOptions((uv_tcp_t *)&hSession->hChildWorkTCP); + uv_read_start((uv_stream_t *)&hSession->hChildWorkTCP, AllocCallback, pTCPBase->ReadStream); + regOK = true; + } else { // USB + HdcUSBBase *pUSBBase = (HdcUSBBase *)hSession->classModule; + WRITE_LOG(LOG_DEBUG, "USB ReadyForWorkThread"); + regOK = pUSBBase->ReadyForWorkThread(hSession); + } + if (regOK && hSession->serverOrDaemon) { + // session handshake step1 + SessionHandShake handshake; + Base::ZeroStruct(handshake); + handshake.banner = HANDSHAKE_MESSAGE; + handshake.sessionId = hSession->sessionId; + handshake.connectKey = hSession->connectKey; + handshake.authType = AUTH_NONE; + string hs = SerialStruct::SerializeToString(handshake); + Send(hSession->sessionId, 0, CMD_KERNEL_HANDSHAKE, (uint8_t *)hs.c_str(), hs.size()); + } + return regOK; +} + +vector HdcSessionBase::BuildCtrlString(InnerCtrlCommand command, uint32_t channelId, uint8_t *data, + int dataSize) +{ + vector ret; + while (true) { + if (dataSize > BUF_SIZE_MICRO) { + break; + } + CtrlStruct ctrl; + Base::ZeroStruct(ctrl); + ctrl.command = command; + ctrl.channelId = channelId; + ctrl.dataSize = dataSize; + if (dataSize > 0 && data != nullptr && memcpy_s(ctrl.data, sizeof(ctrl.data), data, dataSize) != EOK) { + break; + } + uint8_t *buf = reinterpret_cast(&ctrl); + ret.insert(ret.end(), buf, buf + sizeof(CtrlStruct)); + break; + } + return ret; +} + +bool HdcSessionBase::DispatchMainThreadCommand(HSession hSession, const CtrlStruct *ctrl) +{ + bool ret = true; + uint32_t channelId = ctrl->channelId; // if send not set, it is zero + switch (ctrl->command) { + case SP_START_SESSION: { + WRITE_LOG(LOG_DEBUG, "Dispatch MainThreadCommand START_SESSION sessionId:%u instance:%s", + hSession->sessionId, hSession->serverOrDaemon ? "server" : "daemon"); + ret = WorkThreadStartSession(hSession); + break; + } + case SP_STOP_SESSION: { + WRITE_LOG(LOG_DEBUG, "Dispatch MainThreadCommand STOP_SESSION sessionId:%u", hSession->sessionId); + auto closeSessionChildThreadTCPHandle = [](uv_handle_t *handle) -> void { + HSession hSession = (HSession)handle->data; + Base::TryCloseHandle((uv_handle_t *)handle); + if (--hSession->uvChildRef == 0) { + uv_stop(&hSession->childLoop); + }; + }; + hSession->uvChildRef += 2; + if (hSession->hChildWorkTCP.loop) { // maybe not use it + ++hSession->uvChildRef; + Base::TryCloseHandle((uv_handle_t *)&hSession->hChildWorkTCP, true, closeSessionChildThreadTCPHandle); + } + Base::TryCloseHandle((uv_handle_t *)&hSession->ctrlPipe[STREAM_WORK], true, + closeSessionChildThreadTCPHandle); + Base::TryCloseHandle((uv_handle_t *)&hSession->dataPipe[STREAM_WORK], true, + closeSessionChildThreadTCPHandle); + break; + } + case SP_ATTACH_CHANNEL: { + if (!serverOrDaemon) { + break; // Only Server has this feature + } + AttachChannel(hSession, channelId); + break; + } + case SP_DEATCH_CHANNEL: { + if (!serverOrDaemon) { + break; // Only Server has this feature + } + DeatchChannel(hSession, channelId); + break; + } + default: + WRITE_LOG(LOG_WARN, "Not support main command"); + ret = false; + break; + } + return ret; +} + +// Several bytes of control instructions, generally do not stick +void HdcSessionBase::ReadCtrlFromMain(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf) +{ + HSession hSession = (HSession)uvpipe->data; + HdcSessionBase *hSessionBase = (HdcSessionBase *)hSession->classInstance; + int formatCommandSize = sizeof(CtrlStruct); + int index = 0; + bool ret = true; + while (true) { + if (nread < 0) { + WRITE_LOG(LOG_DEBUG, "SessionCtrl failed,%s", uv_strerror(nread)); + ret = false; + break; + } + if (nread % formatCommandSize != 0) { + WRITE_LOG(LOG_FATAL, "ReadCtrlFromMain size failed, nread == %d", nread); + ret = false; + break; + } + CtrlStruct *ctrl = reinterpret_cast(buf->base + index); + if (!(ret = hSessionBase->DispatchMainThreadCommand(hSession, ctrl))) { + ret = false; + break; + } + index += sizeof(CtrlStruct); + if (index >= nread) { + break; + } + } + delete[] buf->base; +} + +void HdcSessionBase::ReChildLoopForSessionClear(HSession hSession) +{ + // Restart loop close task + ClearOwnTasks(hSession, 0); + auto clearTaskForSessionFinish = [](uv_idle_t *handle) -> void { + HSession hSession = (HSession)handle->data; + for (auto v : *hSession->mapTask) { + HTaskInfo hTask = (HTaskInfo)v.second; + if (!hTask->taskFree) + return; + } + // all task has been free + uv_close((uv_handle_t *)handle, Base::CloseIdleCallback); + uv_stop(&hSession->childLoop); // stop ReChildLoopForSessionClear pendding + }; + Base::IdleUvTask(&hSession->childLoop, hSession, clearTaskForSessionFinish); + uv_run(&hSession->childLoop, UV_RUN_DEFAULT); + // clear + Base::TryCloseLoop(&hSession->childLoop, "Session childUV"); +} + +void HdcSessionBase::SessionWorkThread(uv_work_t *arg) +{ + int childRet = 0; + HSession hSession = (HSession)arg->data; + HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; + uv_loop_init(&hSession->childLoop); + hSession->hWorkChildThread = uv_thread_self(); + if ((childRet = uv_tcp_init(&hSession->childLoop, &hSession->ctrlPipe[STREAM_WORK])) < 0) { + WRITE_LOG(LOG_DEBUG, "SessionCtrl err1, %s", uv_strerror(childRet)); + } + if ((childRet = uv_tcp_open(&hSession->ctrlPipe[STREAM_WORK], hSession->ctrlFd[STREAM_WORK])) < 0) { + WRITE_LOG(LOG_DEBUG, "SessionCtrl err2, %s fd:%d", uv_strerror(childRet), hSession->ctrlFd[STREAM_WORK]); + } + uv_read_start((uv_stream_t *)&hSession->ctrlPipe[STREAM_WORK], Base::AllocBufferCallback, ReadCtrlFromMain); + WRITE_LOG(LOG_DEBUG, "!!!Workthread run begin, sessionId:%u instance:%s", hSession->sessionId, + thisClass->serverOrDaemon ? "server" : "daemon"); + uv_run(&hSession->childLoop, UV_RUN_DEFAULT); // work pendding + WRITE_LOG(LOG_DEBUG, "!!!Workthread run again, sessionId:%u", hSession->sessionId); + // main loop has exit + thisClass->ReChildLoopForSessionClear(hSession); // work pending again + hSession->childCleared = true; + WRITE_LOG(LOG_DEBUG, "!!!Workthread run finish, sessionId:%u workthread:%p", hSession->sessionId, uv_thread_self()); +} + +// clang-format off +void HdcSessionBase::LogMsg(const uint32_t sessionId, const uint32_t channelId, + MessageLevel level, const char *msg, ...) +// clang-format on +{ + va_list vaArgs; + va_start(vaArgs, msg); + string log = Base::StringFormat(msg, vaArgs); + va_end(vaArgs); + vector buf; + buf.push_back(level); + buf.insert(buf.end(), log.c_str(), log.c_str() + log.size()); + ServerCommand(sessionId, channelId, CMD_KERNEL_ECHO, buf.data(), buf.size()); +} + +// Heavy and time-consuming work was putted in the new thread to do, and does +// not occupy the main thread +bool HdcSessionBase::DispatchTaskData(HSession hSession, const uint32_t channelId, const uint16_t command, + uint8_t *payload, int payloadSize) +{ + bool ret = false; + while (true) { + HTaskInfo hTaskInfo = AdminTask(OP_QUERY, hSession, channelId, nullptr); + if (!hTaskInfo) { + WRITE_LOG(LOG_DEBUG, "New HTaskInfo"); + hTaskInfo = new TaskInformation(); + hTaskInfo->channelId = channelId; + hTaskInfo->sessionId = hSession->sessionId; + hTaskInfo->runLoop = &hSession->childLoop; + hTaskInfo->serverOrDaemon = serverOrDaemon; + } + if (hTaskInfo->taskStop) { + WRITE_LOG(LOG_DEBUG, "RedirectToTask jump stopped task:%d", channelId); + break; + } + if (hTaskInfo->taskFree) { + WRITE_LOG(LOG_DEBUG, "Jump delete HTaskInfo"); + break; + } + bool result = RedirectToTask(hTaskInfo, hSession, channelId, command, payload, payloadSize); + if (!hTaskInfo->hasInitial) { + AdminTask(OP_ADD, hSession, channelId, hTaskInfo); + hTaskInfo->hasInitial = true; + } + if (result) { + ret = true; + } + break; + } + return ret; +} + +void HdcSessionBase::PostStopInstanceMessage(bool restart) +{ + PushAsyncMessage(0, ASYNC_STOP_MAINLOOP, nullptr, 0); + WRITE_LOG(LOG_DEBUG, "StopDaemon has sended"); + wantRestart = restart; +} +} // namespace Hdc diff --git a/services/flashd/common/session.h b/services/flashd/common/session.h new file mode 100755 index 00000000..fe580717 --- /dev/null +++ b/services/flashd/common/session.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_SESSION_H +#define HDC_SESSION_H +#include "common.h" + +namespace Hdc { +enum TaskType { TYPE_UNITY, TYPE_SHELL, TASK_FILE, TASK_FORWARD, TASK_APP, TASK_UPDATER }; + +class HdcSessionBase { +public: + enum AuthType { AUTH_NONE, AUTH_TOKEN, AUTH_SIGNATURE, AUTH_PUBLICKEY, AUTH_OK }; + struct SessionHandShake { + string banner; // must first index + // auth none + uint8_t authType; + uint32_t sessionId; + string connectKey; + string buf; + }; + struct CtrlStruct { + InnerCtrlCommand command; + uint32_t channelId; + uint8_t dataSize; + uint8_t data[BUF_SIZE_MICRO]; + }; + struct PayloadProtect { // reserve for encrypt and decrypt + uint32_t channelId; + uint32_t commandFlag; + uint8_t checkSum; // enable it will be lose about 20% speed + uint8_t vCode; + }; + + HdcSessionBase(bool serverOrDaemonIn); + virtual ~HdcSessionBase(); + virtual void AttachChannel(HSession hSession, const uint32_t channelId) {}; + virtual void DeatchChannel(HSession hSession, const uint32_t channelId) {}; + virtual bool RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, + const uint16_t command, uint8_t *payload, const int payloadSize) + { + return true; + } + virtual void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) + { + } + // Thread security interface for global stop programs + void PostStopInstanceMessage(bool restart = false); + void ReMainLoopForInstanceClear(); + // server, Two parameters in front of call can be empty + void LogMsg(const uint32_t sessionId, const uint32_t channelId, MessageLevel level, const char *msg, ...); + static void AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf); + static void MainAsyncCallback(uv_async_t *handle); + static void FinishWriteSessionTCP(uv_write_t *req, int status); + static void SessionWorkThread(uv_work_t *arg); + static void ReadCtrlFromMain(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf); + static void ReadCtrlFromSession(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf); + HSession QueryUSBDeviceRegister(void *pDev, int busIDIn, int devIDIn); + HSession MallocSession(bool serverOrDaemon, const ConnType connType, void *classModule, uint32_t sessionId = 0); + void FreeSession(const uint32_t sessionId); + void WorkerPendding(); + int OnRead(HSession hSession, uint8_t *bufPtr, const int bufLen); + int Send(const uint32_t sessionId, const uint32_t channelId, const uint16_t commandFlag, const uint8_t *data, + const int dataSize); + int SendByProtocol(HSession hSession, uint8_t *bufPtr, const int bufLen); + HSession AdminSession(const uint8_t op, const uint32_t sessionId, HSession hInput); + int FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read); + void PushAsyncMessage(const uint32_t sessionId, const uint8_t method, const void *data, const int dataSize); + HTaskInfo AdminTask(const uint8_t op, HSession hSession, const uint32_t channelId, HTaskInfo hInput); + bool DispatchTaskData(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, + int payloadSize); + void EnumUSBDeviceRegister(void (*pCallBack)(HSession hSession)); + void ClearOwnTasks(HSession hSession, const uint32_t channelIDInput); + virtual bool FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, + int payloadSize) + { + return true; + } + virtual bool ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command, + uint8_t *bufPtr, const int size) + { + return true; + } + virtual bool RemoveInstanceTask(const uint8_t op, HTaskInfo hTask) + { + return true; + } + bool WantRestart() + { + return wantRestart; + } + static vector BuildCtrlString(InnerCtrlCommand command, uint32_t channelId, uint8_t *data, int dataSize); + uv_loop_t loopMain; + bool serverOrDaemon; + uv_async_t asyncMainLoop; + uv_rwlock_t mainAsync; + list lstMainThreadOP; + void *ctxUSB; + +protected: + struct PayloadHead { + uint8_t flag[2]; + uint8_t reserve[2]; // encrypt'flag or others options + uint8_t protocolVer; + uint16_t headSize; + uint32_t dataSize; + } __attribute__((packed)); + void ClearSessions(); + virtual void JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO) + { + } + // must be define in haderfile, cannot in cpp file + template + bool TaskCommandDispatch(HTaskInfo hTaskInfo, uint8_t taskType, const uint16_t command, uint8_t *payload, + const int payloadSize) + { + bool ret = true; + T *ptrTask = nullptr; + if (!hTaskInfo->hasInitial) { + ptrTask = new T(hTaskInfo); + hTaskInfo->taskClass = ptrTask; + hTaskInfo->taskType = taskType; + } else { + ptrTask = (T *)hTaskInfo->taskClass; + } + if (!ptrTask->CommandDispatch(command, payload, payloadSize)) { + ptrTask->TaskFinish(); + } + return ret; + } + template bool DoTaskRemove(HTaskInfo hTaskInfo, const uint8_t op) + { + T *ptrTask = (T *)hTaskInfo->taskClass; + if (OP_CLEAR == op) { + ptrTask->StopTask(); + } else if (OP_REMOVE == op) { + if (!ptrTask->ReadyForRelease()) { + return false; + } + delete ptrTask; + } + return true; + } + bool wantRestart; + +private: + virtual void ClearInstanceResource() + { + } + int DecryptPayload(HSession hSession, PayloadHead *payloadHeadBe, uint8_t *encBuf); + bool DispatchMainThreadCommand(HSession hSession, const CtrlStruct *ctrl); + bool DispatchSessionThreadCommand(uv_stream_t *uvpipe, HSession hSession, const uint8_t *baseBuf, + const int bytesIO); + bool BeginRemoveTask(HTaskInfo hTask); + bool TryRemoveTask(HTaskInfo hTask); + void ReChildLoopForSessionClear(HSession hSession); + void FreeSessionContinue(HSession hSession); + static void FreeSessionFinally(uv_idle_t *handle); + static void AsyncMainLoopTask(uv_idle_t *handle); + static void FreeSessionOpeate(uv_timer_t *handle); + int MallocSessionByConnectType(HSession hSession); + void FreeSessionByConnectType(HSession hSession); + bool WorkThreadStartSession(HSession hSession); + uint32_t GetSessionPseudoUid(); + + map mapSession; + uv_rwlock_t lockMapSession; + std::atomic sessionRef = 0; + const uint8_t payloadProtectStaticVcode = 0x09; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/common/task.cpp b/services/flashd/common/task.cpp new file mode 100755 index 00000000..11461858 --- /dev/null +++ b/services/flashd/common/task.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "task.h" + +namespace Hdc { +// ----------------------------------------------------------- +// notice!!! The constructor is called at the Child thread, so in addition to initialization, do not excess actions, if +// destructor is required, please clean up in the subclasses. +HdcTaskBase::HdcTaskBase(HTaskInfo hTaskInfo) +{ + taskInfo = hTaskInfo; + loopTask = hTaskInfo->runLoop; + clsSession = hTaskInfo->ownerSessionClass; + childReady = false; + singalStop = false; + refCount = 0; +} + +HdcTaskBase::~HdcTaskBase() +{ + WRITE_LOG(LOG_DEBUG, "~HdcTaskBase"); +} + +bool HdcTaskBase::ReadyForRelease() +{ + return refCount == 0; +} + +// Only the Task work thread call is allowed to use only when Workfortask returns FALSE. +void HdcTaskBase::TaskFinish() +{ + uint8_t count = 1; + SendToAnother(CMD_KERNEL_CHANNEL_CLOSE, &count, 1); + WRITE_LOG(LOG_DEBUG, "HdcTaskBase::TaskFinish notify"); +} + +bool HdcTaskBase::SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size) +{ + if (singalStop) { + return false; + } + HdcSessionBase *sessionBase = reinterpret_cast(taskInfo->ownerSessionClass); + return sessionBase->Send(taskInfo->sessionId, taskInfo->channelId, command, bufPtr, size) > 0; +} + +void HdcTaskBase::LogMsg(MessageLevel level, const char *msg, ...) +{ + va_list vaArgs; + va_start(vaArgs, msg); + string log = Base::StringFormat(msg, vaArgs); + va_end(vaArgs); + HdcSessionBase *sessionBase = reinterpret_cast(clsSession); + sessionBase->LogMsg(taskInfo->sessionId, taskInfo->channelId, level, log.c_str()); +} + +void HdcTaskBase::SendRawData(uint8_t *bufPtr, const int size) +{ + HdcSessionBase *sessionBase = (HdcSessionBase *)clsSession; + sessionBase->ServerCommand(taskInfo->sessionId, + taskInfo->channelId, CMD_KERNEL_ECHO_RAW, bufPtr, size); +} + +bool HdcTaskBase::ServerCommand(const uint16_t command, uint8_t *bufPtr, const int size) +{ + HdcSessionBase *hSession = (HdcSessionBase *)taskInfo->ownerSessionClass; + return hSession->ServerCommand(taskInfo->sessionId, taskInfo->channelId, command, bufPtr, size); +} + +// cross thread +int HdcTaskBase::ThreadCtrlCommunicate(const uint8_t *bufPtr, const int size) +{ + HdcSessionBase *sessionBase = (HdcSessionBase *)taskInfo->ownerSessionClass; + HSession hSession = sessionBase->AdminSession(OP_QUERY, taskInfo->sessionId, nullptr); + if (!hSession) { + return -1; + } + uv_stream_t *handleStream = nullptr; + if (uv_thread_self() == hSession->hWorkThread) { + handleStream = (uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN]; + } else if (uv_thread_self() == hSession->hWorkChildThread) { + handleStream = (uv_stream_t *)&hSession->ctrlPipe[STREAM_WORK]; + } else { + return ERR_GENERIC; + } + return Base::SendToStream(handleStream, bufPtr, size); +} +} \ No newline at end of file diff --git a/services/flashd/common/task.h b/services/flashd/common/task.h new file mode 100755 index 00000000..0d0d5a67 --- /dev/null +++ b/services/flashd/common/task.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_TASK_H +#define HDC_TASK_H +#include "common.h" + +namespace Hdc { +// Only allow inheritance +class HdcTaskBase { +public: + HdcTaskBase(HTaskInfo hTaskInfo); + virtual ~HdcTaskBase(); + virtual bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) + { + return true; + } + // The following two functions are used to clean up. To ensure that subclasses are safely cleaned, each subclass is + // directly instantified of these two virtual functions. + virtual void StopTask() + { + singalStop = true; // default opeartion + } + bool ReadyForRelease(); + void TaskFinish(); + void SendRawData(uint8_t *bufPtr, const int size); +protected: // D/S==daemon/server + bool SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size); // D / S corresponds to the Task class + void LogMsg(MessageLevel level, const char *msg, ...); // D / S log Send to Client + bool ServerCommand(const uint16_t command, uint8_t *bufPtr, const int size); // D / s command is sent to Server + int ThreadCtrlCommunicate(const uint8_t *bufPtr, const int size); // main thread and session thread + + uv_loop_t *loopTask; // childuv pointer + void *clsSession; + // Task has stopped running. When Task is officially running, set True as soon as possible, set FALSE after the last + // step, when the value is false, the Task class will be destructured as soon as possible + bool childReady; // Subcompulents have been prepared + bool singalStop; // Request stop signal + HTaskInfo taskInfo; + uint32_t refCount; + +private: +}; +} // namespace Hdc + +#endif \ No newline at end of file diff --git a/services/flashd/common/tcp.cpp b/services/flashd/common/tcp.cpp new file mode 100755 index 00000000..18f267c7 --- /dev/null +++ b/services/flashd/common/tcp.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "tcp.h" + +namespace Hdc { +HdcTCPBase::HdcTCPBase(const bool serverOrDaemonIn, void *ptrMainBase) +{ + // Calling the initialization + InitialChildClass(serverOrDaemonIn, ptrMainBase); +} + +HdcTCPBase::~HdcTCPBase() +{ +} + +// Subclasses must be explicitly called +void HdcTCPBase::InitialChildClass(const bool serverOrDaemonIn, void *ptrMainBase) +{ + serverOrDaemon = serverOrDaemonIn; + clsMainBase = ptrMainBase; +} + +void HdcTCPBase::RecvUDP(uv_udp_t *handle, ssize_t nread, const uv_buf_t *rcvbuf, const struct sockaddr *addr, + unsigned flags) +{ + while (true) { + HdcTCPBase *thisClass = (HdcTCPBase *)handle->data; + if (nread <= 0) { + // ==0 finish;<0 error + break; + } + WRITE_LOG(LOG_DEBUG, "RecvUDP %s", rcvbuf->base); + if (strncmp(rcvbuf->base, HANDSHAKE_MESSAGE.c_str(), HANDSHAKE_MESSAGE.size())) { + break; + } + thisClass->RecvUDPEntry(addr, handle, rcvbuf); + break; + } + delete[] rcvbuf->base; +} + +void HdcTCPBase::AllocStreamUDP(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) +{ + int bufLen = BUF_SIZE_DEFAULT; + char *pRecvBuf = (char *)new uint8_t[bufLen](); + if (!pRecvBuf) { + return; + } + buf->base = pRecvBuf; + buf->len = bufLen; +} + +void HdcTCPBase::SendUDPFinish(uv_udp_send_t *req, int status) +{ + delete req; +} + +void HdcTCPBase::ReadStream(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf) +{ + HSession hSession = (HSession)tcp->data; + HdcTCPBase *thisClass = (HdcTCPBase *)hSession->classModule; + HdcSessionBase *hSessionBase = (HdcSessionBase *)thisClass->clsMainBase; + bool ret = false; + while (true) { + if (nread == UV_ENOBUFS) { + WRITE_LOG(LOG_DEBUG, "Session IOBuf max"); + break; + } else if (nread < 0) { + // I originally in the IO main thread, no need to send asynchronous messages, close the socket as soon as + // possible + WRITE_LOG(LOG_DEBUG, "HdcTCPBase::ReadStream < 0 %s", uv_strerror(nread)); + break; + } + if (hSessionBase->FetchIOBuf(hSession, hSession->ioBuf, nread) < 0) { + break; + } + ret = true; + break; + } + if (!ret) { + // The first time is closed first, prevent the write function from continuing to write + Base::TryCloseHandle(reinterpret_cast(tcp)); + hSessionBase->FreeSession(hSession->sessionId); + } +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/tcp.h b/services/flashd/common/tcp.h new file mode 100755 index 00000000..e7f32a27 --- /dev/null +++ b/services/flashd/common/tcp.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_TCP_H +#define HDC_TCP_H +#include "common.h" + +namespace Hdc { +class HdcTCPBase { +public: + HdcTCPBase(const bool serverOrDaemonIn, void *ptrMainBase); + virtual ~HdcTCPBase(); + static void ReadStream(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf); + +protected: + virtual void RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf) + { + } + static void RecvUDP( + uv_udp_t *handle, ssize_t nread, const uv_buf_t *rcvbuf, const struct sockaddr *addr, unsigned flags); + static void SendUDPFinish(uv_udp_send_t *req, int status); + static void AllocStreamUDP(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf); + + void *clsMainBase; + bool serverOrDaemon; + +private: + void InitialChildClass(const bool serverOrDaemonIn, void *ptrMainBase); +}; +} // namespace Hdc + +#endif \ No newline at end of file diff --git a/services/flashd/common/transfer.cpp b/services/flashd/common/transfer.cpp new file mode 100755 index 00000000..fc983cfd --- /dev/null +++ b/services/flashd/common/transfer.cpp @@ -0,0 +1,417 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "transfer.h" +#include "serial_struct.h" +#include +#ifdef HARMONY_PROJECT +#include +#endif + +namespace Hdc { +constexpr uint64_t HDC_TIME_CONVERT_BASE = 1000000000; + +HdcTransferBase::HdcTransferBase(HTaskInfo hTaskInfo) + : HdcTaskBase(hTaskInfo) +{ + ResetCtx(&ctxNow, true); + commandBegin = 0; + commandData = 0; +} + +HdcTransferBase::~HdcTransferBase() +{ + WRITE_LOG(LOG_DEBUG, "~HdcTransferBase"); +}; + +bool HdcTransferBase::ResetCtx(CtxFile *context, bool full) +{ + context->fsOpenReq.data = context; + context->fsCloseReq.data = context; + context->thisClass = this; + context->closeNotify = false; + context->indexIO = 0; + context->loop = loopTask; + context->cb = OnFileIO; + if (full) { + context->localPath = ""; + context->remotePath = ""; + context->transferBegin = 0; + context->taskQueue.clear(); + Base::ZeroStruct(ctxNow.transferConfig); + } + return true; +} + +int HdcTransferBase::SimpleFileIO(CtxFile *context, uint64_t index, uint8_t *sendBuf, int bytes) +{ + // The first 8 bytes file offset + uint8_t *buf = new uint8_t[bytes](); + CtxFileIO *ioContext = new CtxFileIO(); + bool ret = false; + while (true) { + if (!buf || !ioContext || bytes < 0) { + break; + } + uv_fs_t *req = &ioContext->fs; + ioContext->bufIO = buf; + ioContext->context = context; + req->data = ioContext; + ++refCount; + if (context->master) { // master just read, and slave just write.when master/read, sendBuf can be nullptr + uv_buf_t iov = uv_buf_init(reinterpret_cast(buf), bytes); + uv_fs_read(context->loop, req, context->fsOpenReq.result, &iov, 1, index, context->cb); + } else { + // The US_FS_WRITE here must be brought into the actual file offset, which cannot be incorporated with local + // accumulated index because UV_FS_WRITE will be executed multiple times and then trigger a callback. + if (bytes > 0 && memcpy_s(ioContext->bufIO, bytes, sendBuf, bytes) != EOK) { + break; + } + uv_buf_t iov = uv_buf_init(reinterpret_cast(ioContext->bufIO), bytes); + uv_fs_write(context->loop, req, context->fsOpenReq.result, &iov, 1, index, context->cb); + } + ret = true; + break; + } + if (!ret) { + WRITE_LOG(LOG_WARN, "SimpleFileIO error"); + if (buf != nullptr) { + delete[] buf; + buf = nullptr; + } + if (ioContext != nullptr) { + delete ioContext; + ioContext = nullptr; + } + return -1; + } + return bytes; +} + +void HdcTransferBase::OnFileClose(uv_fs_t *req) +{ + uv_fs_req_cleanup(req); + CtxFile *context = (CtxFile *)req->data; + HdcTransferBase *thisClass = (HdcTransferBase *)context->thisClass; + if (context->closeNotify) { + // close-step2 + thisClass->WhenTransferFinish(context); + } + --thisClass->refCount; + return; +} + +void HdcTransferBase::SetFileTime(CtxFile *context) +{ + if (!context->transferConfig.holdTimestamp) { + return; + } + if (!context->transferConfig.mtime) { + return; + } + uv_fs_t fs; + double aTimeSec = static_cast(context->transferConfig.atime) / HDC_TIME_CONVERT_BASE; + double mTimeSec = static_cast(context->transferConfig.mtime) / HDC_TIME_CONVERT_BASE; + uv_fs_futime(nullptr, &fs, context->fsOpenReq.result, aTimeSec, mTimeSec, nullptr); + uv_fs_req_cleanup(&fs); +} + +bool HdcTransferBase::SendIOPayload(CtxFile *context, int index, uint8_t *data, int dataSize) +{ + TransferPayload payloadHead; + string head; + int compressSize = 0; + int sendBufSize = payloadPrefixReserve + dataSize; + uint8_t *sendBuf = new uint8_t[sendBufSize](); + if (!sendBuf) { + return false; + } + payloadHead.compressType = context->transferConfig.compressType; + payloadHead.uncompressSize = dataSize; + payloadHead.index = index; + if (dataSize > 0) { + switch (payloadHead.compressType) { +#ifdef HARMONY_PROJECT + case COMPRESS_LZ4: { + compressSize = LZ4_compress_default((const char *)data, (char *)sendBuf + payloadPrefixReserve, + dataSize, dataSize); + break; + } +#endif + default: { // COMPRESS_NONE + if (memcpy_s(sendBuf + payloadPrefixReserve, sendBufSize - payloadPrefixReserve, data, dataSize) + != EOK) { + delete[] sendBuf; + return false; + } + compressSize = dataSize; + break; + } + } + } + payloadHead.compressSize = compressSize; + head = SerialStruct::SerializeToString(payloadHead); + if (head.size() + 1 > payloadPrefixReserve) { + delete[] sendBuf; + return false; + } + int errCode = memcpy_s(sendBuf, sendBufSize, head.c_str(), head.size() + 1); + if (errCode != EOK) { + delete[] sendBuf; + return false; + } + bool ret = SendToAnother(commandData, sendBuf, payloadPrefixReserve + compressSize) > 0; + delete[] sendBuf; + return ret; +} + +void HdcTransferBase::OnFileIO(uv_fs_t *req) +{ + bool tryFinishIO = false; + CtxFileIO *contextIO = (CtxFileIO *)req->data; + CtxFile *context = (CtxFile *)contextIO->context; + HdcTransferBase *thisClass = (HdcTransferBase *)context->thisClass; + uint8_t *bufIO = contextIO->bufIO; + uv_fs_req_cleanup(req); + --thisClass->refCount; + while (true) { + if (req->result < 0) { + WRITE_LOG(LOG_DEBUG, "OnFileIO error: %s", uv_strerror((int)req->result)); + context->closeNotify = true; + tryFinishIO = true; + break; + } + context->indexIO += req->result; + if (req->fs_type == UV_FS_READ) { + if (!thisClass->SendIOPayload(context, context->indexIO - req->result, bufIO, req->result)) { + tryFinishIO = true; + break; + } + if (context->indexIO < context->fileSize) { + // read continue until result >0, let single file packet +packet header less than GetMaxBufSize() + constexpr auto maxBufFactor = 0.8; + thisClass->SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize() * maxBufFactor); + } + } else if (req->fs_type == UV_FS_WRITE) { // write + if (context->indexIO >= context->fileSize) { + // The active end must first read it first, but you can't make Finish first, because Slave may not + // end.Only slave receives complete talents Finish + context->closeNotify = true; + tryFinishIO = true; + thisClass->SetFileTime(context); + } + } else { + tryFinishIO = true; + } + break; + } + delete[] bufIO; + delete contextIO; // Req is part of the Contextio structure, no free release + if (tryFinishIO) { + // close-step1 + ++thisClass->refCount; + uv_fs_close(thisClass->loopTask, &context->fsCloseReq, context->fsOpenReq.result, OnFileClose); + } +} + +void HdcTransferBase::OnFileOpen(uv_fs_t *req) +{ + CtxFile *context = (CtxFile *)req->data; + HdcTransferBase *thisClass = (HdcTransferBase *)context->thisClass; + uv_fs_req_cleanup(req); + WRITE_LOG(LOG_DEBUG, "Filemod openfile:%s", context->localPath.c_str()); + --thisClass->refCount; + if (req->result < 0) { + thisClass->LogMsg(MSG_FAIL, "Error opening file: %s, path:%s", uv_strerror((int)req->result), + context->localPath.c_str()); + thisClass->TaskFinish(); + return; + } + thisClass->ResetCtx(context); + if (context->master) { + // init master + uv_fs_t fs; + Base::ZeroStruct(fs.statbuf); + uv_fs_fstat(nullptr, &fs, context->fsOpenReq.result, nullptr); + TransferConfig &st = context->transferConfig; + st.fileSize = fs.statbuf.st_size; + st.optionalName = context->localName; + if (st.holdTimestamp) { + st.atime = fs.statbuf.st_atim.tv_sec * HDC_TIME_CONVERT_BASE + fs.statbuf.st_atim.tv_nsec; + st.mtime = fs.statbuf.st_mtim.tv_sec * HDC_TIME_CONVERT_BASE + fs.statbuf.st_mtim.tv_nsec; + } + st.path = context->remotePath; + // update ctxNow=context child value + context->fileSize = st.fileSize; + + uv_fs_req_cleanup(&fs); + thisClass->CheckMaster(context); + } else { // write + thisClass->SendToAnother(thisClass->commandBegin, nullptr, 0); + } +} + +bool HdcTransferBase::MatchPackageExtendName(string fileName, string extName) +{ + bool match = false; + int subfixIndex = fileName.rfind(extName); + if ((fileName.size() - subfixIndex) != extName.size()) { + return false; + } + match = true; + return match; +} + +// filter can be empty +int HdcTransferBase::GetSubFiles(const char *path, string filter, vector *out) +{ + int retNum = 0; + uv_fs_t req; + Base::ZeroStruct(req); + uv_dirent_t dent; + vector filterStrings; + if (!strlen(path)) { + return retNum; + } + if (filter.size()) { + Base::SplitString(filter, ";", filterStrings); + } + + if (uv_fs_scandir(nullptr, &req, path, 0, nullptr) < 0) { + uv_fs_req_cleanup(&req); + return retNum; + } + while (uv_fs_scandir_next(&req, &dent) != UV_EOF) { + // Skip. File + if (strcmp(dent.name, ".") == 0 || strcmp(dent.name, "..") == 0) + continue; + if (!(static_cast(dent.type) & UV_DIRENT_FILE)) + continue; + string fileName = dent.name; + for (auto &&s : filterStrings) { + int subfixIndex = fileName.rfind(s); + if ((fileName.size() - subfixIndex) != s.size()) + continue; + string fullPath = string(path) + "/"; + fullPath += fileName; + out->push_back(fullPath); + ++retNum; + } + } + uv_fs_req_cleanup(&req); + return retNum; +} + +// https://en.cppreference.com/w/cpp/filesystem/is_directory +// return true if file exist, false if file not exist +bool HdcTransferBase::SmartSlavePath(string &cwd, string &localPath, const char *optName) +{ + if (taskInfo->serverOrDaemon) { + // slave and server + ExtractRelativePath(cwd, localPath); + } + if (Base::CheckDirectoryOrPath(localPath.c_str(), true, false)) { + return true; + } + uv_fs_t req; + int r = uv_fs_lstat(nullptr, &req, localPath.c_str(), nullptr); + uv_fs_req_cleanup(&req); + if (r == 0 && req.statbuf.st_mode & S_IFDIR) { // is dir + localPath = Base::StringFormat("%s%c%s", localPath.c_str(), Base::GetPathSep(), optName); + } + return false; +} + +bool HdcTransferBase::RecvIOPayload(CtxFile *context, uint8_t *data, int dataSize) +{ + uint8_t *clearBuf = nullptr; + string serialStrring((char *)data, payloadPrefixReserve); + TransferPayload pld; + bool ret = false; + SerialStruct::ParseFromString(pld, serialStrring); + clearBuf = new uint8_t[pld.uncompressSize](); + if (!clearBuf) { + return false; + } + int clearSize = 0; + if (pld.compressSize > 0) { + switch (pld.compressType) { +#ifdef HARMONY_PROJECT + case COMPRESS_LZ4: { + clearSize = LZ4_decompress_safe((const char *)data + payloadPrefixReserve, (char *)clearBuf, + pld.compressSize, pld.uncompressSize); + break; + } +#endif + default: { // COMPRESS_NONE + if (memcpy_s(clearBuf, pld.uncompressSize, data + payloadPrefixReserve, pld.compressSize) != EOK) { + delete[] clearBuf; + return false; + } + clearSize = pld.compressSize; + break; + } + } + } + while (true) { + if ((uint32_t)clearSize != pld.uncompressSize) { + break; + } + if (SimpleFileIO(context, pld.index, clearBuf, clearSize) < 0) { + break; + } + ret = true; + break; + } + delete[] clearBuf; + return ret; +} + +bool HdcTransferBase::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + bool ret = true; + while (true) { + if (command == commandBegin) { + CtxFile *context = &ctxNow; + SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize()); + context->transferBegin = Base::GetRuntimeMSec(); + } else if (command == commandData) { + // The size of the actual HOST end may be larger than maxbuf + constexpr auto doubleSize = 2; + if (payloadSize > MAX_SIZE_IOBUF * doubleSize || payloadSize < 0) { + ret = false; + break; + } + // Note, I will trigger FileIO after multiple times. + CtxFile *context = &ctxNow; + if (!RecvIOPayload(context, payload, payloadSize)) { + ret = false; + break; + } + } else { + // Other subclass commands + } + break; + } + return ret; +} + +void HdcTransferBase::ExtractRelativePath(string &cwd, string &path) +{ + bool absPath = Base::IsAbsolutePath(path); + if (!absPath) { + path = cwd + path; + } +} +} // namespace Hdc diff --git a/services/flashd/common/transfer.h b/services/flashd/common/transfer.h new file mode 100755 index 00000000..c03b3dea --- /dev/null +++ b/services/flashd/common/transfer.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_TRANSFER_H +#define HDC_TRANSFER_H +#include "common.h" + +namespace Hdc { +class HdcTransferBase : public HdcTaskBase { +public: + enum CompressType { COMPRESS_NONE, COMPRESS_LZ4, COMPRESS_LZ77, COMPRESS_LZMA, COMPRESS_BROTLI }; + // used for child class + struct TransferConfig { + uint64_t fileSize; + uint64_t atime; // ns + uint64_t mtime; // ns + string options; + string path; + string optionalName; + bool updateIfNew; + uint8_t compressType; + bool holdTimestamp; + string functionName; + string clientCwd; + string reserve1; + string reserve2; + }; + // used for HdcTransferBase. just base class use, not public + struct TransferPayload { + uint64_t index; + uint8_t compressType; + uint32_t compressSize; + uint32_t uncompressSize; + }; + HdcTransferBase(HTaskInfo hTaskInfo); + virtual ~HdcTransferBase(); + virtual void StopTask() + { + } + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); + +protected: + // Static file context + struct CtxFile { // The structure cannot be initialized by MEMSET + bool master; // Document transmission initiative + bool closeNotify; + void *thisClass; + uint64_t fileSize; + uint64_t indexIO; // Id or written IO bytes + uv_loop_t *loop; + uv_fs_cb cb; + string localName; + string localPath; + string remotePath; + uv_fs_t fsOpenReq; + uv_fs_t fsCloseReq; + uint64_t transferBegin; + vector taskQueue; + TransferConfig transferConfig; // Used for network IO configuration initialization + }; + // Just app-mode use + enum AppModType { + APPMOD_NONE, + APPMOD_INSTALL, + APPMOD_UNINSTALL, + APPMOD_SIDELOAD, + }; + + static void OnFileOpen(uv_fs_t *req); + static void OnFileClose(uv_fs_t *req); + int GetSubFiles(const char *path, string filter, vector *out); + virtual void CheckMaster(CtxFile *context) + { + } + virtual void WhenTransferFinish(CtxFile *context) + { + } + bool MatchPackageExtendName(string fileName, string extName); + bool ResetCtx(CtxFile *context, bool full = false); + bool SmartSlavePath(string &cwd, string &localPath, const char *optName); + void SetFileTime(CtxFile *context); + void ExtractRelativePath(string &cwd, string &path); + + CtxFile ctxNow; + uint16_t commandBegin; + uint16_t commandData; + const string CMD_OPTION_CLIENTCWD = "-cwd"; + const uint8_t payloadPrefixReserve = 64; +private: + // dynamic IO context + struct CtxFileIO { + uv_fs_t fs; + uint8_t *bufIO; + CtxFile *context; + }; + static void OnFileIO(uv_fs_t *req); + int SimpleFileIO(CtxFile *context, uint64_t index, uint8_t *sendBuf, int bytesIO); + bool SendIOPayload(CtxFile *context, int index, uint8_t *data, int dataSize); + bool RecvIOPayload(CtxFile *context, uint8_t *data, int dataSize); +}; +} // namespace Hdc + +#endif \ No newline at end of file diff --git a/services/flashd/common/usb.cpp b/services/flashd/common/usb.cpp new file mode 100755 index 00000000..db39a445 --- /dev/null +++ b/services/flashd/common/usb.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "usb.h" + +namespace Hdc { +HdcUSBBase::HdcUSBBase(const bool serverOrDaemonIn, void *ptrMainBase) +{ + serverOrDaemon = serverOrDaemonIn; + clsMainBase = ptrMainBase; + modRunning = true; +} + +HdcUSBBase::~HdcUSBBase() +{ +} + +void HdcUSBBase::ReadUSB(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) +{ + HSession hSession = (HSession)stream->data; + HdcSessionBase *hSessionBase = (HdcSessionBase *)hSession->classInstance; + if (hSessionBase->FetchIOBuf(hSession, hSession->ioBuf, nread) < 0) { + hSessionBase->FreeSession(hSession->sessionId); + } +} + +bool HdcUSBBase::ReadyForWorkThread(HSession hSession) +{ + // Server-end USB IO is handed over to each sub-thread, only the daemon is still read by the main IO to distribute + // to each sub-thread by DataPipe. + if (uv_tcp_init(&hSession->childLoop, &hSession->dataPipe[STREAM_WORK]) + || uv_tcp_open(&hSession->dataPipe[STREAM_WORK], hSession->dataFd[STREAM_WORK])) { + WRITE_LOG(LOG_FATAL, "USBBase ReadyForWorkThread init child TCP failed"); + return false; + } + hSession->dataPipe[STREAM_WORK].data = hSession; + HdcSessionBase *pSession = (HdcSessionBase *)hSession->classInstance; + Base::SetTcpOptions(&hSession->dataPipe[STREAM_WORK]); + if (uv_read_start((uv_stream_t *)&hSession->dataPipe[STREAM_WORK], pSession->AllocCallback, ReadUSB)) { + WRITE_LOG(LOG_FATAL, "USBBase ReadyForWorkThread child TCP read failed"); + return false; + } + WRITE_LOG(LOG_DEBUG, "USBBase ReadyForWorkThread finish"); + return true; +}; + +// USB big data stream, block transmission, mainly to prevent accidental data packets from writing through EP port, +// inserting the send queue causes the program to crash +int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) +{ + // Format:USBPacket1 payload1...USBPacketn payloadn; + // [USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] + int maxIOSize = Base::GetMaxBufSize(); + int sizeUSBPacketHead = sizeof(USBHead); + int singleSize = maxIOSize - sizeUSBPacketHead; + int iMod = length % singleSize; + int iCount = (length - iMod) / singleSize + 1; + int offset = 0; + int i = 0; // It doesn't matter of 0 or 1, start from 1 to send it according to the serial number. + uint8_t *ioBuf = new uint8_t[maxIOSize](); + if (!ioBuf) { + return ERR_BUF_ALLOC; + } + for (i = 0; i < iCount; ++i) { + USBHead *pUSBHead = (USBHead *)ioBuf; + int errCode = memcpy_s(pUSBHead->flag, sizeof(pUSBHead->flag), PACKET_FLAG.c_str(), PACKET_FLAG.size()); + if (errCode != EOK) { + offset = ERR_BUF_COPY; + break; + } + pUSBHead->sessionId = hSession->sessionId; + if (i != iCount - 1) { + pUSBHead->dataSize = static_cast(singleSize); + } else { + pUSBHead->dataSize = static_cast(iMod); + pUSBHead->option = pUSBHead->option | USB_OPTION_TAIL; + } + uint8_t *payload = ioBuf + sizeUSBPacketHead; + if (EOK != memcpy_s(payload, maxIOSize - sizeUSBPacketHead, (uint8_t *)data + offset, pUSBHead->dataSize)) { + offset = ERR_BUF_COPY; + break; + } + offset += pUSBHead->dataSize; + if (SendUSBRaw(hSession, ioBuf, sizeUSBPacketHead + pUSBHead->dataSize) <= 0) { + offset = ERR_IO_FAIL; + break; + } + } + delete[] ioBuf; + return offset; +} + +int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize) +{ + HUSB hUSB = hSession->hUSB; + vector &bufRecv = hUSB->bufRecv; + bufRecv.insert(bufRecv.end(), appendData, appendData + dataSize); + int ret = RET_SUCCESS; + while (bufRecv.size() > sizeof(USBHead)) { + USBHead *usbHeader = (USBHead *)bufRecv.data(); + if (memcmp(usbHeader->flag, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { + WRITE_LOG(LOG_FATAL, "Error usb packet"); + ret = ERR_BUF_CHECK; + break; + } + if (bufRecv.size() < sizeof(USBHead) + usbHeader->dataSize) { + WRITE_LOG(LOG_DEBUG, "SendToHdcStream not enough"); + break; // successful , but not enough + } + if (usbHeader->sessionId != hSession->sessionId) { + // Only server do it here, daemon 'SendUsbSoftReset' no use + // hilog + ctrl^C to reproduction scene + // + // Because the USB-reset API does not work on all platforms, the last session IO data may be + // recveived, we need to ignore it. + if (hSession->serverOrDaemon && !hUSB->resetIO) { + WRITE_LOG(LOG_WARN, "SendToHdcStream sessionId not matched"); + SendUsbSoftReset(hUSB, usbHeader->sessionId); + hUSB->resetIO = true; + } + } else { + // usb data to logic + if (Base::SendToStream(stream, bufRecv.data() + sizeof(USBHead), usbHeader->dataSize) < 0) { + ret = ERR_IO_FAIL; + WRITE_LOG(LOG_FATAL, "Error usb send to stream"); + break; + } + } + bufRecv.erase(bufRecv.begin(), bufRecv.begin() + sizeof(USBHead) + usbHeader->dataSize); + } + return ret; +} +} \ No newline at end of file diff --git a/services/flashd/common/usb.h b/services/flashd/common/usb.h new file mode 100755 index 00000000..8b49c54c --- /dev/null +++ b/services/flashd/common/usb.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_USB_H +#define HDC_USB_H +#include "common.h" + +namespace Hdc { +class HdcUSBBase { +public: + HdcUSBBase(const bool serverOrDaemonIn, void *ptrMainBase); + virtual ~HdcUSBBase(); + virtual int SendUSBRaw(HSession hSession, uint8_t *data, const int length) + { + return 0; + } + virtual bool ReadyForWorkThread(HSession hSession); + virtual void SendUsbSoftReset(HUSB hUSB, uint32_t sessionId) {}; + int SendUSBBlock(HSession hSession, uint8_t *data, const int length); + static void ReadUSB(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); + int SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize); + +protected: + void *clsMainBase; + bool serverOrDaemon; + bool modRunning; +}; +} // namespace Hdc + +#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon.cpp b/services/flashd/daemon/daemon.cpp new file mode 100755 index 00000000..fa34ef8b --- /dev/null +++ b/services/flashd/daemon/daemon.cpp @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "daemon.h" +#include "../common/serial_struct.h" +#include + +namespace Hdc { +HdcDaemon::HdcDaemon(bool serverOrDaemonIn) + : HdcSessionBase(serverOrDaemonIn) +{ + clsTCPServ = nullptr; + clsUSBServ = nullptr; + clsJdwp = nullptr; + enableSecure = false; +} + +HdcDaemon::~HdcDaemon() +{ + WRITE_LOG(LOG_DEBUG, "~HdcDaemon"); +} + +void HdcDaemon::ClearInstanceResource() +{ + TryStopInstance(); + Base::TryCloseLoop(&loopMain, "HdcDaemon::~HdcDaemon"); + if (clsTCPServ) { + delete (HdcDaemonTCP *)clsTCPServ; + clsTCPServ = nullptr; + } + if (clsUSBServ) { + delete (HdcDaemonUSB *)clsUSBServ; + clsUSBServ = nullptr; + } + if (clsJdwp) { + delete (HdcJdwp *)clsJdwp; + clsJdwp = nullptr; + } + WRITE_LOG(LOG_DEBUG, "~HdcDaemon finish"); +} + +void HdcDaemon::TryStopInstance() +{ + ClearSessions(); + if (clsTCPServ) { + WRITE_LOG(LOG_DEBUG, "Stop TCP"); + ((HdcDaemonTCP *)clsTCPServ)->Stop(); + } + if (clsUSBServ) { + WRITE_LOG(LOG_DEBUG, "Stop USB"); + ((HdcDaemonUSB *)clsUSBServ)->Stop(); + } + ((HdcJdwp *)clsJdwp)->Stop(); + // workaround temply remove MainLoop instance clear + ReMainLoopForInstanceClear(); + WRITE_LOG(LOG_DEBUG, "Stop loopmain"); +} + +void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB) +{ + WRITE_LOG(LOG_DEBUG, "HdcDaemon InitMod"); + if (bEnableTCP) { + // tcp + clsTCPServ = new HdcDaemonTCP(false, this); + ((HdcDaemonTCP *)clsTCPServ)->Initial(); + } + if (bEnableUSB) { + // usb + clsUSBServ = new HdcDaemonUSB(false, this); + ((HdcDaemonUSB *)clsUSBServ)->Initial(); + } + + clsJdwp = new HdcJdwp(&loopMain); + ((HdcJdwp *)clsJdwp)->Initial(); + + // enable security + char value[4] = "0"; + Base::GetHdcProperty("ro.hdc.secure", value, sizeof(value)); + string secure = value; + enableSecure = (Base::Trim(secure) == "1"); +} + +void HdcDaemon::SendAndCloseChannel(HSession hSession, const uint32_t channelId, const std::string &info) +{ + Send(hSession->sessionId, channelId, CMD_KERNEL_ECHO_RAW, (uint8_t *)info.data(), info.size()); + uint8_t count = 1; + Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1); +} + +// clang-format off +#ifdef HDC_SUPPORT_FLASHD +bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, + const uint16_t command, uint8_t *payload, const int payloadSize) +{ + bool ret = true; + hTaskInfo->ownerSessionClass = this; + switch (command) { + case CMD_UNITY_REBOOT: + case CMD_UNITY_RUNMODE: + ret = TaskCommandDispatch(hTaskInfo, TYPE_UNITY, command, payload, payloadSize); + break; + case CMD_UPDATER_UPDATE_INIT: + case CMD_UPDATER_FLASH_INIT: + case CMD_UPDATER_CHECK: + case CMD_UPDATER_BEGIN: + case CMD_UPDATER_DATA: + case CMD_UPDATER_FINISH: + case CMD_UPDATER_ERASE: + case CMD_UPDATER_FORMAT: + case CMD_UPDATER_PROGRESS: + ret = TaskCommandDispatch(hTaskInfo, TASK_UPDATER, command, payload, payloadSize); + break; + default: + SendAndCloseChannel(hSession, channelId, "Command not support in flashd\n"); + break; + } + return ret; +} +#else +bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, + const uint16_t command, uint8_t *payload, const int payloadSize) +{ + bool ret = true; + hTaskInfo->ownerSessionClass = this; + switch (command) { + case CMD_UNITY_EXECUTE: + case CMD_UNITY_REMOUNT: + case CMD_UNITY_REBOOT: + case CMD_UNITY_RUNMODE: + case CMD_UNITY_HILOG: + case CMD_UNITY_ROOTRUN: + case CMD_UNITY_TERMINATE: + case CMD_UNITY_BUGREPORT_INIT: + case CMD_UNITY_JPID: + ret = TaskCommandDispatch(hTaskInfo, TYPE_UNITY, command, payload, payloadSize); + break; + case CMD_SHELL_INIT: + case CMD_SHELL_DATA: + ret = TaskCommandDispatch(hTaskInfo, TYPE_SHELL, command, payload, payloadSize); + break; + case CMD_FILE_CHECK: + case CMD_FILE_DATA: + case CMD_FILE_FINISH: + case CMD_FILE_INIT: + case CMD_FILE_BEGIN: + ret = TaskCommandDispatch(hTaskInfo, TASK_FILE, command, payload, payloadSize); + break; + // One-way function, so fewer options + case CMD_APP_CHECK: + case CMD_APP_DATA: + case CMD_APP_UNINSTALL: + ret = TaskCommandDispatch(hTaskInfo, TASK_APP, command, payload, payloadSize); + break; + case CMD_FORWARD_INIT: + case CMD_FORWARD_CHECK: + case CMD_FORWARD_ACTIVE_SLAVE: + case CMD_FORWARD_DATA: + case CMD_FORWARD_FREE_CONTEXT: + case CMD_FORWARD_CHECK_RESULT: + ret = TaskCommandDispatch(hTaskInfo, TASK_FORWARD, command, payload, payloadSize); + break; + case CMD_UPDATER_CHECK: + case CMD_UPDATER_ERASE: + case CMD_UPDATER_FORMAT: + SendAndCloseChannel(hSession, channelId, "Command not support in hdcd\n"); + break; + default: + ret = false; + break; + } + return ret; +} +// clang-format on +#endif + +bool HdcDaemon::HandDaemonAuth(HSession hSession, const uint32_t channelId, SessionHandShake &handshake) +{ + bool ret = false; + switch (handshake.authType) { + case AUTH_NONE: { // AUTH_NONE -> AUTH + hSession->tokenRSA = Base::GetRandomString(SHA_DIGEST_LENGTH); + handshake.authType = AUTH_TOKEN; + handshake.buf = hSession->tokenRSA; + string bufString = SerialStruct::SerializeToString(handshake); + Send(hSession->sessionId, channelId, CMD_KERNEL_HANDSHAKE, (uint8_t *)bufString.c_str(), bufString.size()); + ret = true; + break; + } + case AUTH_SIGNATURE: { + // When Host is first connected to the device, the signature authentication is inevitable, and the + // certificate verification must be triggered. + // + // When the certificate is verified, the client sends a public key to the device, triggered the system UI + // jump out dialog, and click the system, the system will store the Host public key certificate in the + // device locally, and the signature authentication will be correct when the subsequent connection is + // connected. + if (!HdcAuth::AuthVerify((uint8_t *)hSession->tokenRSA.c_str(), (uint8_t *)handshake.buf.c_str(), + handshake.buf.size())) { + // Next auth + handshake.authType = AUTH_TOKEN; + handshake.buf = hSession->tokenRSA; + string bufString = SerialStruct::SerializeToString(handshake); + Send(hSession->sessionId, channelId, CMD_KERNEL_HANDSHAKE, (uint8_t *)bufString.c_str(), + bufString.size()); + break; + } + ret = true; + break; + } + case AUTH_PUBLICKEY: { + ret = HdcAuth::PostUIConfirm(handshake.buf); + WRITE_LOG(LOG_DEBUG, "Auth host OK, postUIConfirm"); + break; + } + default: + break; + } + return ret; +} + +bool HdcDaemon::DaemonSessionHandshake(HSession hSession, const uint32_t channelId, uint8_t *payload, int payloadSize) +{ + // session handshake step2 + string s = string((char *)payload, payloadSize); + SessionHandShake handshake; + string err; + SerialStruct::ParseFromString(handshake, s); + // banner to check is parse ok... + if (handshake.banner != HANDSHAKE_MESSAGE) { + hSession->availTailIndex = 0; + WRITE_LOG(LOG_FATAL, "Recv server-hello failed"); + return false; + } + if (handshake.authType == AUTH_NONE) { + // daemon handshake 1st packet + uint32_t unOld = hSession->sessionId; + hSession->sessionId = handshake.sessionId; + hSession->connectKey = handshake.connectKey; + AdminSession(OP_UPDATE, unOld, hSession); + if (clsUSBServ != nullptr) { + (reinterpret_cast(clsUSBServ))->OnNewHandshakeOK(hSession->sessionId); + } + + handshake.sessionId = 0; + handshake.connectKey = ""; + } + if (enableSecure && !HandDaemonAuth(hSession, channelId, handshake)) { + return false; + } + // handshake auth OK.Can append the sending device information to HOST + char hostName[BUF_SIZE_MEDIUM] = ""; + size_t len = sizeof(hostName); + uv_os_gethostname(hostName, &len); + handshake.authType = AUTH_OK; + handshake.buf = hostName; + string bufString = SerialStruct::SerializeToString(handshake); + Send(hSession->sessionId, channelId, CMD_KERNEL_HANDSHAKE, (uint8_t *)bufString.c_str(), bufString.size()); + hSession->handshakeOK = true; + return true; +} + +bool HdcDaemon::FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, + int payloadSize) +{ + bool ret = true; + if (!hSession->handshakeOK && command != CMD_KERNEL_HANDSHAKE) { + ret = false; + return ret; + } + switch (command) { + case CMD_KERNEL_HANDSHAKE: { + // session handshake step2 + ret = DaemonSessionHandshake(hSession, channelId, payload, payloadSize); + break; + } + case CMD_KERNEL_CHANNEL_CLOSE: { // Daemon is only cleaning up the Channel task + ClearOwnTasks(hSession, channelId); + if (*payload == 1) { + --(*payload); + Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); + } + ret = true; + break; + } + default: + ret = DispatchTaskData(hSession, channelId, command, payload, payloadSize); + break; + } + return ret; +} + +bool HdcDaemon::RemoveInstanceTask(const uint8_t op, HTaskInfo hTask) +{ + bool ret = true; + switch (hTask->taskType) { + case TYPE_UNITY: + ret = DoTaskRemove(hTask, op); + break; + case TYPE_SHELL: + ret = DoTaskRemove(hTask, op); + break; + case TASK_FILE: + ret = DoTaskRemove(hTask, op); + break; + case TASK_FORWARD: + ret = DoTaskRemove(hTask, op); + break; + case TASK_APP: + ret = DoTaskRemove(hTask, op); + break; +#ifdef HDC_SUPPORT_FLASHD + case TASK_UPDATER: + ret = DoTaskRemove(hTask, op); + break; +#endif + default: + ret = false; + break; + } + return ret; +} + +bool HdcDaemon::ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command, + uint8_t *bufPtr, const int size) +{ + return Send(sessionId, channelId, command, (uint8_t *)bufPtr, size) > 0; +} + +void HdcDaemon::JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO) +{ + uint32_t pid = *(uint32_t *)(buf + 1); + uint32_t fd = *(uint32_t *)(buf + 5); // 5 : fd offset + ((HdcJdwp *)clsJdwp)->SendJdwpNewFD(pid, fd); +}; +} // namespace Hdc diff --git a/services/flashd/daemon/daemon.h b/services/flashd/daemon/daemon.h new file mode 100755 index 00000000..4eb7df29 --- /dev/null +++ b/services/flashd/daemon/daemon.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DAEMON_H +#define HDC_DAEMON_H +#include "daemon_common.h" + +namespace Hdc { +class HdcDaemon : public HdcSessionBase { +public: + HdcDaemon(bool serverOrDaemonIn); + virtual ~HdcDaemon(); + void InitMod(bool bEnableTCP, bool bEnableUSB); + bool FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, + const int payloadSize); + bool ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command, uint8_t *bufPtr, + const int size); + void *clsTCPServ; + void *clsUSBServ; + void *clsJdwp; + +private: + bool RemoveInstanceTask(const uint8_t op, HTaskInfo hTask); + bool RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, const uint16_t command, + uint8_t *payload, const int payloadSize); + void SendAndCloseChannel(HSession hSession, const uint32_t channelId, const std::string &info); + void JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO); + bool HandDaemonAuth(HSession hSession, const uint32_t channelId, SessionHandShake &handshake); + void ClearInstanceResource(); + bool DaemonSessionHandshake(HSession hSession, const uint32_t channelId, uint8_t *payload, int payloadSize); + void TryStopInstance(); + + bool enableSecure; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon_app.cpp b/services/flashd/daemon/daemon_app.cpp new file mode 100755 index 00000000..4f04dc93 --- /dev/null +++ b/services/flashd/daemon/daemon_app.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "daemon_app.h" + +namespace Hdc { +HdcDaemonApp::HdcDaemonApp(HTaskInfo hTaskInfo) + : HdcTransferBase(hTaskInfo) +{ + commandBegin = CMD_APP_BEGIN; + commandData = CMD_APP_DATA; + funcAppModFinish = nullptr; +} + +HdcDaemonApp::~HdcDaemonApp() +{ + WRITE_LOG(LOG_DEBUG, "~HdcDaemonApp"); +} + +bool HdcDaemonApp::ReadyForRelease() +{ + if (!HdcTaskBase::ReadyForRelease()) { + return false; + } + if (!asyncCommand.ReadyForRelease()) { + return false; + } + return true; +} + +bool HdcDaemonApp::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + if (!HdcTransferBase::CommandDispatch(command, payload, payloadSize)) { + return false; + } + bool ret = true; + switch (command) { + case CMD_APP_CHECK: { + string tmpData = "/data/local/tmp/"; + string tmpSD = "/sdcard/tmp/"; + string dstPath = tmpData; + string bufString((char *)payload, payloadSize); + SerialStruct::ParseFromString(ctxNow.transferConfig, bufString); + // update transferconfig to main context + ctxNow.master = false; + ctxNow.fsOpenReq.data = &ctxNow; + // -lrtsdpg, -l -r -t -s.., + if (ctxNow.transferConfig.functionName == CMDSTR_APP_INSTALL + && ctxNow.transferConfig.options.find("s") != std::string::npos) { + dstPath = tmpSD; + } +#ifdef HDC_PCDEBUG + char tmpPath[256] = ""; + size_t size = 256; + uv_os_tmpdir(tmpPath, &size); + dstPath = tmpPath; + dstPath += Base::GetPathSep(); +#endif + dstPath += ctxNow.transferConfig.optionalName; + ctxNow.localPath = dstPath; + ctxNow.transferBegin = Base::GetRuntimeMSec(); + ctxNow.fileSize = ctxNow.transferConfig.fileSize; + ++refCount; + uv_fs_open(loopTask, &ctxNow.fsOpenReq, ctxNow.localPath.c_str(), + UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IRUSR, OnFileOpen); + break; + } + case CMD_APP_UNINSTALL: { + // This maybe has a command implanting risk, since it is a controllable device, it can be ignored + string bufString(reinterpret_cast(payload), payloadSize); + PackageShell(false, "", bufString); + break; + } + default: + break; + } + return ret; +}; + +bool HdcDaemonApp::AsyncInstallFinish(bool finish, int64_t exitStatus, const string result) +{ + if (mode == APPMOD_INSTALL) { + unlink(ctxNow.localPath.c_str()); + } + asyncCommand.DoRelease(); + string echo = result; + echo = Base::ReplaceAll(echo, "\n", " "); + vector vecBuf; + vecBuf.push_back(mode); + vecBuf.push_back(exitStatus == 0); + vecBuf.insert(vecBuf.end(), (uint8_t *)echo.c_str(), (uint8_t *)echo.c_str() + echo.size()); + SendToAnother(CMD_APP_FINISH, vecBuf.data(), vecBuf.size()); + --refCount; +#ifdef UNIT_TEST + Base::WriteBinFile((UT_TMP_PATH + "/appinstall.result").c_str(), (uint8_t *)MESSAGE_SUCCESS.c_str(), + MESSAGE_SUCCESS.size(), true); +#endif + return true; +} + +void HdcDaemonApp::PackageShell(bool installOrUninstall, const char *options, const string package) +{ + ++refCount; + // asynccmd Other processes, no RunningProtect protection + chmod(package.c_str(), 0644); // 0644 : permission + string doBuf; + if (installOrUninstall) { + doBuf = Base::StringFormat("bm install %s -p %s", options, package.c_str()); + } else { + doBuf = Base::StringFormat("bm uninstall %s -n %s", options, package.c_str()); + } + funcAppModFinish = std::bind(&HdcDaemonApp::AsyncInstallFinish, this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3); + if (installOrUninstall) { + mode = APPMOD_INSTALL; + } else { + mode = APPMOD_UNINSTALL; + } + asyncCommand.Initial(loopTask, funcAppModFinish); + asyncCommand.ExecuteCommand(doBuf); +} + +void HdcDaemonApp::Sideload(const char *pathOTA) +{ + mode = APPMOD_SIDELOAD; + LogMsg(MSG_OK, "[placeholders] sideload %s", pathOTA); + TaskFinish(); + unlink(pathOTA); +} + +void HdcDaemonApp::WhenTransferFinish(CtxFile *context) +{ + if (ctxNow.transferConfig.functionName == CMDSTR_APP_SIDELOAD) { + Sideload(context->localPath.c_str()); + } else if (ctxNow.transferConfig.functionName == CMDSTR_APP_INSTALL) { + PackageShell(true, context->transferConfig.options.c_str(), context->localPath.c_str()); + } else { + } +}; +} \ No newline at end of file diff --git a/services/flashd/daemon/daemon_app.h b/services/flashd/daemon/daemon_app.h new file mode 100755 index 00000000..7546fc39 --- /dev/null +++ b/services/flashd/daemon/daemon_app.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DAEMON_APP_H +#define HDC_DAEMON_APP_H +#include "daemon_common.h" + +namespace Hdc { +class HdcDaemonApp : public HdcTransferBase { +public: + HdcDaemonApp(HTaskInfo hTaskInfo); + virtual ~HdcDaemonApp(); + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); + bool ReadyForRelease(); + +private: + void WhenTransferFinish(CtxFile *context); + void PackageShell(bool installOrUninstall, const char *options, const string package); + bool AsyncInstallFinish(bool finish, int64_t exitStatus, const string result); + void Sideload(const char *pathOTA); + + AsyncCmd asyncCommand; + AsyncCmd::CmdResultCallback funcAppModFinish; + AppModType mode = APPMOD_NONE; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon_common.h b/services/flashd/daemon/daemon_common.h new file mode 100755 index 00000000..35786e03 --- /dev/null +++ b/services/flashd/daemon/daemon_common.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DAEMON_COMMON_H +#define HDC_DAEMON_COMMON_H + +// clang-format off +#include "../common/common.h" +#include "../common/define.h" +#include "../common/file.h" +#include "../common/forward.h" +#include "../common/async_cmd.h" +#include "../common/serial_struct.h" +#include "jdwp.h" +#include "daemon.h" +#include "daemon_unity.h" +#include "daemon_tcp.h" +#include "daemon_app.h" +#include "daemon_usb.h" +#include "daemon_forward.h" +#ifdef HDC_SUPPORT_FLASHD +#include "daemon_updater.h" +#endif +#include "shell.h" + +// clang-format on + +namespace Hdc { +} +#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon_forward.cpp b/services/flashd/daemon/daemon_forward.cpp new file mode 100755 index 00000000..25ddb710 --- /dev/null +++ b/services/flashd/daemon/daemon_forward.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "daemon_forward.h" + +namespace Hdc { +HdcDaemonForward::HdcDaemonForward(HTaskInfo hTaskInfo) + : HdcForwardBase(hTaskInfo) +{ +} + +HdcDaemonForward::~HdcDaemonForward() +{ +} + +void HdcDaemonForward::SetupJdwpPointCallBack(uv_idle_t *handle) +{ + HCtxForward ctxPoint = (HCtxForward)handle->data; + HdcDaemonForward *thisClass = reinterpret_cast(ctxPoint->thisClass); + thisClass->SetupPointContinue(ctxPoint, 1); // It usually works + Base::TryCloseHandle((const uv_handle_t *)handle, Base::CloseIdleCallback); + WRITE_LOG(LOG_DEBUG, "Setup JdwpPointCallBack finish"); + --thisClass->refCount; + return; +} + +bool HdcDaemonForward::SetupJdwpPoint(HCtxForward ctxPoint) +{ + HdcDaemon *daemon = (HdcDaemon *)taskInfo->ownerSessionClass; + HdcJdwp *clsJdwp = (HdcJdwp *)daemon->clsJdwp; + uint32_t pid = std::stol(ctxPoint->localArgs[1]); + if (ctxPoint->checkPoint) { // checke + bool ret = clsJdwp->CheckPIDExist(pid); + SetupPointContinue(ctxPoint, (int)ret); + WRITE_LOG(LOG_DEBUG, "Jdwp jump checkpoint"); + return true; + } + // do slave connect + // fd[0] for forward, fd[1] for jdwp + // forward to close fd[0], fd[1] for jdwp close + int fds[2] = { 0 }; + bool ret = false; + Base::CreateSocketPair(fds); + if (uv_tcp_init(loopTask, &ctxPoint->tcp)) { + return ret; + } + ctxPoint->tcp.data = ctxPoint; + if (uv_tcp_open(&ctxPoint->tcp, fds[0])) { + return ret; + } + constexpr auto len = sizeof(uint32_t); + uint8_t flag[1 + len + len]; + flag[0] = SP_JDWP_NEWFD; + if (memcpy_s(flag + 1, sizeof(flag) - 1, &pid, len) || + memcpy_s(flag + 1 + len, sizeof(flag) - len - 1, &fds[1], len)) { + return ret; + } + if (ThreadCtrlCommunicate(flag, sizeof(flag)) > 0) { + ret = true; + } + WRITE_LOG(LOG_DEBUG, "SendJdwpNewFD Finish,ret:%d fd0:%d fd1:%d", ret, fds[0], fds[1]); + if (!ret) { + Base::CloseSocketPair(fds); + return ret; + } + + ++refCount; + Base::IdleUvTask(loopTask, ctxPoint, SetupJdwpPointCallBack); + return ret; +} +} \ No newline at end of file diff --git a/services/flashd/daemon/daemon_forward.h b/services/flashd/daemon/daemon_forward.h new file mode 100755 index 00000000..5dfae60a --- /dev/null +++ b/services/flashd/daemon/daemon_forward.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DAEMON_FORWARD_H +#define HDC_DAEMON_FORWARD_H +#include "daemon_common.h" + +namespace Hdc { +class HdcDaemonForward : public HdcForwardBase { +public: + HdcDaemonForward(HTaskInfo hTaskInfo); + virtual ~HdcDaemonForward(); + +private: + bool SetupJdwpPoint(HCtxForward ctxPoint); + static void SetupJdwpPointCallBack(uv_idle_t *handle); +}; +} // namespace Hdc + +#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon_tcp.cpp b/services/flashd/daemon/daemon_tcp.cpp new file mode 100755 index 00000000..64d16aeb --- /dev/null +++ b/services/flashd/daemon/daemon_tcp.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "daemon_tcp.h" + +namespace Hdc { +HdcDaemonTCP::HdcDaemonTCP(const bool serverOrDaemonIn, void *ptrMainBase) + : HdcTCPBase(serverOrDaemonIn, ptrMainBase) +{ + // If the listening value for the property setting is obtained, it will be 0 randomly assigned. + char strTCPPort[BUF_SIZE_TINY] = ""; + const uint16_t BUFF_SIZE = 8; + Base::GetHdcProperty("persist.hdc.port", strTCPPort, BUFF_SIZE); + tcpListenPort = atoi(strTCPPort); + if (tcpListenPort <= 0) { + tcpListenPort = 10178; // 10178 def port + } + Base::ZeroStruct(servUDP); + Base::ZeroStruct(servTCP); +#ifdef HDC_DEBUG + const uint16_t DEBUG_TCP_PORT = 10178; + tcpListenPort = DEBUG_TCP_PORT; +#endif +} + +HdcDaemonTCP::~HdcDaemonTCP() +{ +} + +void HdcDaemonTCP::Stop() +{ + Base::TryCloseHandle((const uv_handle_t *)&servUDP); + Base::TryCloseHandle((const uv_handle_t *)&servTCP); + WRITE_LOG(LOG_DEBUG, "~HdcDaemonTCP"); +} + +void HdcDaemonTCP::TransmitConfig(const sockaddr *addrSrc, uv_udp_t *handle) +{ + char srcIP[BUF_SIZE_TINY] = ""; + struct sockaddr addrSrcIPPort; + uv_udp_send_t *req = new uv_udp_send_t(); + if (!req) { + return; + } + string sendBuf = Base::StringFormat("%s-%d", HANDSHAKE_MESSAGE.c_str(), tcpListenPort); + uv_buf_t sndbuf = uv_buf_init((char *)sendBuf.c_str(), sendBuf.size()); + uv_ip4_name((sockaddr_in *)addrSrc, srcIP, sizeof(srcIP)); + uv_ip4_addr(srcIP, DEFAULT_PORT, (sockaddr_in *)&addrSrcIPPort); + uv_udp_send(req, handle, &sndbuf, 1, &addrSrcIPPort, SendUDPFinish); +} + +void HdcDaemonTCP::AcceptClient(uv_stream_t *server, int status) +{ + uv_loop_t *ptrLoop = server->loop; + uv_tcp_t *pServTCP = (uv_tcp_t *)server; + HdcDaemonTCP *thisClass = (HdcDaemonTCP *)pServTCP->data; + HdcSessionBase *ptrConnect = (HdcSessionBase *)thisClass->clsMainBase; + HdcSessionBase *daemon = reinterpret_cast(thisClass->clsMainBase); + const uint16_t maxWaitTime = UV_DEFAULT_INTERVAL; + auto ctrl = daemon->BuildCtrlString(SP_START_SESSION, 0, nullptr, 0); + HSession hSession = ptrConnect->MallocSession(false, CONN_TCP, thisClass); + if (!hSession) { + return; + } + if (uv_accept(server, (uv_stream_t *)&hSession->hWorkTCP) < 0) { + goto Finish; + } + if ((hSession->fdChildWorkTCP = Base::DuplicateUvSocket(&hSession->hWorkTCP)) < 0) { + goto Finish; + }; + Base::TryCloseHandle((uv_handle_t *)&hSession->hWorkTCP); + Base::StartWorkThread(ptrLoop, ptrConnect->SessionWorkThread, Base::FinishWorkThread, hSession); + // wait for thread up + while (hSession->childLoop.active_handles == 0) { + usleep(maxWaitTime); + } + Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); + return; +Finish: + ptrConnect->FreeSession(hSession->sessionId); +} + +void HdcDaemonTCP::RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf) +{ + TransmitConfig(addrSrc, handle); +} + +void HdcDaemonTCP::SetUDPListen() +{ + struct sockaddr_in addr; + int r; + HdcSessionBase *ptrConnect = (HdcSessionBase *)clsMainBase; + // udp broadcast + servUDP.data = this; + r = uv_udp_init(&ptrConnect->loopMain, &servUDP); + r = uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr); + r = uv_udp_bind(&servUDP, (const struct sockaddr *)&addr, UV_UDP_REUSEADDR); + r = uv_udp_recv_start(&servUDP, AllocStreamUDP, RecvUDP); +} + +// Set the daemon-side TCP listening +int HdcDaemonTCP::SetTCPListen() +{ + // tcp listen + HdcSessionBase *ptrConnect = (HdcSessionBase *)clsMainBase; + servTCP.data = this; + struct sockaddr_in addr; + int namelen; + const int DEFAULT_BACKLOG = 128; + + uv_tcp_init(&ptrConnect->loopMain, &servTCP); + uv_ip4_addr("0.0.0.0", tcpListenPort, &addr); // tcpListenPort == 0 + uv_tcp_bind(&servTCP, (const struct sockaddr *)&addr, 0); + if (uv_listen((uv_stream_t *)&servTCP, DEFAULT_BACKLOG, (uv_connection_cb)AcceptClient)) { + return ERR_API_FAIL; + } + // Get listen port + Base::ZeroStruct(addr); + namelen = sizeof(addr); + if (uv_tcp_getsockname(&servTCP, (sockaddr *)&addr, &namelen)) { + return ERR_API_FAIL; + } + tcpListenPort = ntohs(addr.sin_port); + return RET_SUCCESS; +} + +int HdcDaemonTCP::Initial() +{ + WRITE_LOG(LOG_DEBUG, "HdcDaemonTCP init"); + SetUDPListen(); + if (SetTCPListen() != RET_SUCCESS) { + WRITE_LOG(LOG_FATAL, "TCP listen failed"); + return ERR_GENERIC; + } +#ifndef UNIT_TEST + WRITE_LOG(LOG_INFO, "TCP listen on port:[%d]", tcpListenPort); +#endif + return RET_SUCCESS; +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/daemon/daemon_tcp.h b/services/flashd/daemon/daemon_tcp.h new file mode 100755 index 00000000..bd399ea6 --- /dev/null +++ b/services/flashd/daemon/daemon_tcp.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DAEMON_TCP_H +#define HDC_DAEMON_TCP_H +#include "daemon_common.h" + +namespace Hdc { +class HdcDaemonTCP : public HdcTCPBase { +public: + HdcDaemonTCP(const bool serverOrDaemonIn, void *ptrMainBase); + virtual ~HdcDaemonTCP(); + void RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf); + uint16_t tcpListenPort; + int Initial(); + void Stop(); + +private: + static void AcceptClient(uv_stream_t *server, int status); + void TransmitConfig(const sockaddr *addrSrc, uv_udp_t *handle); + int SetTCPListen(); + void SetUDPListen(); + + uv_tcp_t servTCP; + uv_udp_t servUDP; +}; +} // namespace Hdc + +#endif diff --git a/services/flashd/daemon/daemon_unity.cpp b/services/flashd/daemon/daemon_unity.cpp new file mode 100755 index 00000000..5a4aa067 --- /dev/null +++ b/services/flashd/daemon/daemon_unity.cpp @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "daemon_unity.h" +#include +#ifdef __MUSL__ +extern "C" { +#include "init_reboot.h" +} +#endif + +namespace Hdc { +HdcDaemonUnity::HdcDaemonUnity(HTaskInfo hTaskInfo) + : HdcTaskBase(hTaskInfo) +{ + currentDataCommand = CMD_KERNEL_ECHO_RAW; // Default output to shelldata +} + +HdcDaemonUnity::~HdcDaemonUnity() +{ + WRITE_LOG(LOG_DEBUG, "HdcDaemonUnity::~HdcDaemonUnity finish"); +} + +void HdcDaemonUnity::StopTask() +{ + asyncCommand.DoRelease(); +}; + +bool HdcDaemonUnity::ReadyForRelease() +{ + if (!HdcTaskBase::ReadyForRelease() || !asyncCommand.ReadyForRelease()) { + return false; + } + return true; +} + +bool HdcDaemonUnity::AsyncCmdOut(bool finish, int64_t exitStatus, const string result) +{ +#ifdef UNIT_TEST + Base::WriteBinFile((UT_TMP_PATH + "/execute.result").c_str(), (uint8_t *)result.c_str(), result.size(), + countUt++ == 0); +#endif + bool ret = false; + bool wantFinish = false; + do { + if (finish) { + wantFinish = true; + ret = true; + --refCount; + break; + } + if (!SendToAnother(currentDataCommand, (uint8_t *)result.c_str(), result.size())) { + break; + } + ret = true; + } while (false); + if (wantFinish) { + TaskFinish(); + } + return ret; +} + +int HdcDaemonUnity::ExecuteShell(const char *shellCommand) +{ + do { + AsyncCmd::CmdResultCallback funcResultOutput; + funcResultOutput = std::bind(&HdcDaemonUnity::AsyncCmdOut, this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3); + if (!asyncCommand.Initial(loopTask, funcResultOutput, + asyncCommand.GetDefaultOption() | asyncCommand.OPTION_READBACK_OUT)) { + break; + } + asyncCommand.ExecuteCommand(shellCommand); + ++refCount; + return RET_SUCCESS; + } while (false); + + TaskFinish(); + WRITE_LOG(LOG_DEBUG, "Shell failed finish"); + return -1; +} + +bool HdcDaemonUnity::FindMountDeviceByPath(const char *toQuery, char *dev) +{ + int fd; + int res; + char *token = nullptr; + const char delims[] = "\n"; + char buf[BUF_SIZE_DEFAULT2]; + + fd = open("/proc/mounts", O_RDONLY | O_CLOEXEC); + if (fd < 0) { + return false; + } + read(fd, buf, sizeof(buf) - 1); + close(fd); + buf[sizeof(buf) - 1] = '\0'; + token = strtok(buf, delims); + + while (token) { + char dir[BUF_SIZE_SMALL] = ""; + int freq; + int passnno; + // clang-format off + res = sscanf_s(token, "%255s %255s %*s %*s %d %d\n", dev, BUF_SIZE_SMALL - 1, + dir, BUF_SIZE_SMALL - 1, &freq, &passnno); + // clang-format on + dev[BUF_SIZE_SMALL - 1] = '\0'; + dir[BUF_SIZE_SMALL - 1] = '\0'; + if (res == 4 && (strcmp(toQuery, dir) == 0)) { // 4 : The correct number of parameters + return true; + } + token = strtok(nullptr, delims); + } + return false; +} + +bool HdcDaemonUnity::RemountPartition(const char *dir) +{ + int fd; + int off = 0; + char dev[BUF_SIZE_SMALL] = ""; + + if (!FindMountDeviceByPath(dir, dev) || strlen(dev) < 4) { // 4 : file count + WRITE_LOG(LOG_DEBUG, "FindMountDeviceByPath failed"); + return false; + } + + if ((fd = open(dev, O_RDONLY | O_CLOEXEC)) < 0) { + WRITE_LOG(LOG_DEBUG, "Open device:%s failed, error:%d", dev, errno); + return false; + } + ioctl(fd, BLKROSET, &off); + close(fd); + + if (mount(dev, dir, "none", MS_REMOUNT, nullptr) < 0) { + WRITE_LOG(LOG_DEBUG, "Mount device failed"); + return false; + } + return true; +} + +bool HdcDaemonUnity::RemountDevice() +{ + if (getuid() != 0) { + LogMsg(MSG_FAIL, "Opearte need running as root"); + return false; + } + struct stat info; + if (!lstat("/vendor", &info) && (info.st_mode & S_IFMT) == S_IFDIR) { + // has vendor + if (!RemountPartition("/vendor")) { + LogMsg(MSG_FAIL, "Mount failed"); + return false; + } + } + if (!lstat("/data", &info) && (info.st_mode & S_IFMT) == S_IFDIR) { + if (!RemountPartition("/data")) { + return false; + } + } + LogMsg(MSG_OK, "Mount finish"); + return true; +} + +bool HdcDaemonUnity::RebootDevice(const string &cmd) +{ + sync(); +#ifndef __MUSL__ + string propertyVal; + if (!cmd.size()) { + propertyVal = "reboot"; + } else { + propertyVal = Base::StringFormat("reboot,%s", cmd.c_str()); + } + return Base::SetHdcProperty(rebootProperty.c_str(), propertyVal.c_str()); +#else + string reason; + if (cmd == "recovery") { + reason = "updater"; + } else if (cmd == "bootloader") { + reason = "NoArgument"; + } else { + reason = cmd; + } + return DoReboot(reason.c_str()); +#endif +} + +bool HdcDaemonUnity::SetDeviceRunMode(void *daemonIn, const char *cmd) +{ + HdcDaemon *daemon = (HdcDaemon *)daemonIn; + WRITE_LOG(LOG_DEBUG, "Set run mode:%s", cmd); + if (!strcmp(CMDSTR_TMODE_USB.c_str(), cmd)) { + Base::SetHdcProperty("persist.hdc.mode", CMDSTR_TMODE_USB.c_str()); + } else if (!strncmp("port", cmd, strlen("port"))) { + Base::SetHdcProperty("persist.hdc.mode", CMDSTR_TMODE_TCP.c_str()); + if (!strncmp("port ", cmd, strlen("port "))) { + const char *port = cmd + 5; + Base::SetHdcProperty("persist.hdc.port", port); + } + } else { + LogMsg(MSG_FAIL, "Unknow command"); + return false; + } + // shutdown + daemon->PostStopInstanceMessage(true); + LogMsg(MSG_OK, "Set device run mode successful."); + return true; +} + +inline bool HdcDaemonUnity::GetHiLog(const char *cmd) +{ + string cmdDo = "hilog"; + if (cmd && !strcmp((char *)cmd, "v")) { + cmdDo += " -v long"; + } + ExecuteShell(cmdDo.c_str()); + return true; +} + +inline bool HdcDaemonUnity::ListJdwpProcess(void *daemonIn) +{ + HdcDaemon *daemon = (HdcDaemon *)daemonIn; + string result = ((HdcJdwp *)daemon->clsJdwp)->GetProcessList(); + if (!result.size()) { + result = EMPTY_ECHO; + } else { + result.erase(result.end() - 1); // remove tail \n + } + LogMsg(MSG_OK, result.c_str()); + return true; +} + +bool HdcDaemonUnity::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + bool ret = true; + HdcDaemon *daemon = (HdcDaemon *)taskInfo->ownerSessionClass; + // Both are not executed, do not need to be detected 'childReady' + string strPayload = string((char *)payload, payloadSize); + switch (command) { + case CMD_UNITY_EXECUTE: { + ExecuteShell((char *)strPayload.c_str()); + break; + } + case CMD_UNITY_REMOUNT: { + ret = false; + RemountDevice(); + break; + } + case CMD_UNITY_REBOOT: { + ret = false; + RebootDevice(strPayload); + break; + } + case CMD_UNITY_RUNMODE: { + ret = false; + SetDeviceRunMode(daemon, strPayload.c_str()); + break; + } + case CMD_UNITY_HILOG: { + GetHiLog(strPayload.c_str()); + break; + } + case CMD_UNITY_ROOTRUN: { + ret = false; + if (payloadSize != 0 && !strcmp((char *)strPayload.c_str(), "r")) { + Base::SetHdcProperty("persist.hdc.root", "0"); + } else { + Base::SetHdcProperty("persist.hdc.root", "1"); + } + daemon->PostStopInstanceMessage(true); + break; + } + case CMD_UNITY_TERMINATE: { + daemon->PostStopInstanceMessage(!strcmp((char *)strPayload.c_str(), "1")); + break; + } + case CMD_UNITY_BUGREPORT_INIT: { + currentDataCommand = CMD_UNITY_BUGREPORT_DATA; + ExecuteShell((char *)CMDSTR_BUGREPORT.c_str()); + break; + } + case CMD_UNITY_JPID: { + ret = false; + ListJdwpProcess(daemon); + break; + } + default: + break; + } + return ret; +}; +} // namespace Hdc diff --git a/services/flashd/daemon/daemon_unity.h b/services/flashd/daemon/daemon_unity.h new file mode 100755 index 00000000..c816487f --- /dev/null +++ b/services/flashd/daemon/daemon_unity.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DAEMON_UNITY_H +#define HDC_DAEMON_UNITY_H +#include "daemon_common.h" + +namespace Hdc { +class HdcDaemonUnity : public HdcTaskBase { +public: + HdcDaemonUnity(HTaskInfo hTaskInfo); + virtual ~HdcDaemonUnity(); + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); + void StopTask(); + bool ReadyForRelease(); + +private: + static void OnFdRead(uv_fs_t *req); + int ExecuteShell(const char *shellCommand); + bool FindMountDeviceByPath(const char *toQuery, char *dev); + bool RemountPartition(const char *dir); + bool RemountDevice(); + bool RebootDevice(const string &cmd); + bool SetDeviceRunMode(void *daemonIn, const char *cmd); + bool GetHiLog(const char *cmd); + bool ListJdwpProcess(void *daemonIn); + bool AsyncCmdOut(bool finish, int64_t exitStatus, const string result); + + const string rebootProperty = "sys.powerctl"; + AsyncCmd asyncCommand; + uint16_t currentDataCommand; +#ifdef UNIT_TEST + int countUt = 0; +#endif +}; +} // namespace Hdc +#endif // HDC_DAEMON_UNITY_H diff --git a/services/flashd/daemon/daemon_usb.cpp b/services/flashd/daemon/daemon_usb.cpp new file mode 100755 index 00000000..6f5a33b6 --- /dev/null +++ b/services/flashd/daemon/daemon_usb.cpp @@ -0,0 +1,498 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "daemon_usb.h" +#include "usb_ffs.h" + +namespace Hdc { +HdcDaemonUSB::HdcDaemonUSB(const bool serverOrDaemonIn, void *ptrMainBase) + : HdcUSBBase(serverOrDaemonIn, ptrMainBase) +{ + Base::ZeroStruct(sendEP); + Base::ZeroStruct(usbHandle); + uv_mutex_init(&sendEP); +} + +HdcDaemonUSB::~HdcDaemonUSB() +{ + // Closed in the IO loop, no longer closing CLOSE ENDPOINT + uv_mutex_destroy(&sendEP); + if (controlEp > 0) { + close(controlEp); + } +} + +void HdcDaemonUSB::Stop() +{ + WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB Stop"); + // Here only clean up the IO-related resources, session related resources clear reason to clean up the session + // module + modRunning = false; + WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB Stop free main session"); + Base::TryCloseHandle((uv_handle_t *)&checkEP); + CloseEndpoint(&usbHandle); + WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB Stop free main session finish"); +} + +string HdcDaemonUSB::GetDevPath(const std::string &path) +{ + DIR *dir = ::opendir(path.c_str()); + if (dir == nullptr) { + WRITE_LOG(LOG_WARN, "%s: cannot open devpath: errno: %d", path.c_str(), errno); + return ""; + } + + string res = USB_FFS_BASE; + string node; + int count = 0; + struct dirent *entry = nullptr; + while ((entry = ::readdir(dir))) { + if (*entry->d_name == '.') { + continue; + } + node = entry->d_name; + ++count; + } + if (count > 1) { + res += "hdc"; + } else { + res += node; + } + ::closedir(dir); + return res; +} + +int HdcDaemonUSB::Initial() +{ + // after Linux-3.8,kernel switch to the USB Function FS + // Implement USB hdc function in user space + WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB init"); + basePath = GetDevPath(USB_FFS_BASE); + if (access((basePath + "/ep0").c_str(), F_OK) != 0) { + WRITE_LOG(LOG_DEBUG, "Only support usb-ffs, make sure kernel3.8+ and usb-ffs enabled, usbmode disabled"); + return -1; + } + HdcDaemon *daemon = (HdcDaemon *)clsMainBase; + WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB::Initiall"); + uv_timer_init(&daemon->loopMain, &checkEP); + checkEP.data = this; + uv_timer_start(&checkEP, WatchEPTimer, 0, TIME_BASE); + return 0; +} + +// DAEMON end USB module USB-FFS EP port connection +int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) +{ + int ret = ERR_GENERIC; + while (true) { + if (controlEp <= 0) { + // After the control port sends the instruction, the device is initialized by the device to the HOST host, + // which can be found for USB devices. Do not send initialization to the EP0 control port, the USB + // device will not be initialized by Host + WRITE_LOG(LOG_DEBUG, "Begin send to control(EP0) for usb descriptor init"); + string ep0Path = basePath + "/ep0"; + if ((controlEp = open(ep0Path.c_str(), O_RDWR)) < 0) { + WRITE_LOG(LOG_WARN, "%s: cannot open control endpoint: errno=%d", ep0Path.c_str(), errno); + break; + } + if (write(controlEp, &USB_FFS_DESC, sizeof(USB_FFS_DESC)) < 0) { + WRITE_LOG(LOG_WARN, "%s: write ffs configs failed: errno=%d", ep0Path.c_str(), errno); + break; + } + if (write(controlEp, &USB_FFS_VALUE, sizeof(USB_FFS_VALUE)) < 0) { + WRITE_LOG(LOG_WARN, "%s: write USB_FFS_VALUE failed: errno=%d", ep0Path.c_str(), errno); + break; + } + // active usbrc,Send USB initialization singal + Base::SetHdcProperty("sys.usb.ffs.ready", "1"); + WRITE_LOG(LOG_DEBUG, "ConnectEPPoint ctrl init finish, set usb-ffs ready"); + } + string outPath = basePath + "/ep1"; + if ((hUSB->bulkOut = open(outPath.c_str(), O_RDWR)) < 0) { + WRITE_LOG(LOG_WARN, "%s: cannot open bulk-out ep: errno=%d", outPath.c_str(), errno); + break; + } + string inPath = basePath + "/ep2"; + if ((hUSB->bulkIn = open(inPath.c_str(), O_RDWR)) < 0) { + WRITE_LOG(LOG_WARN, "%s: cannot open bulk-in ep: errno=%d", inPath.c_str(), errno); + break; + } + // cannot open with O_CLOEXEC, must fcntl + fcntl(controlEp, F_SETFD, FD_CLOEXEC); + fcntl(hUSB->bulkOut, F_SETFD, FD_CLOEXEC); + fcntl(hUSB->bulkIn, F_SETFD, FD_CLOEXEC); + + WRITE_LOG(LOG_DEBUG, "New bulk in\\out open bulkout:%d bulkin:%d", hUSB->bulkOut, hUSB->bulkIn); + hUSB->bufRecv.clear(); + ret = RET_SUCCESS; + break; + } + if (ret != RET_SUCCESS) { + CloseEndpoint(hUSB, true); + } + return ret; +} + +void HdcDaemonUSB::CloseEndpoint(HUSB hUSB, bool closeCtrlEp) +{ + if (hUSB->bulkIn > 0) { + close(hUSB->bulkIn); + hUSB->bulkIn = 0; + } + if (hUSB->bulkOut > 0) { + close(hUSB->bulkOut); + hUSB->bulkOut = 0; + } + if (controlEp > 0 && closeCtrlEp) { + close(controlEp); + controlEp = 0; + } + isAlive = false; + WRITE_LOG(LOG_FATAL, "DaemonUSB close endpoint"); +} + +void HdcDaemonUSB::ResetOldSession(const uint32_t sessionId) +{ + HdcDaemon *daemon = reinterpret_cast(clsMainBase); + HSession hSession = daemon->AdminSession(OP_QUERY, sessionId, nullptr); + if (hSession == nullptr) { + return; + } + hSession->hUSB->resetIO = true; + // The Host side is restarted, but the USB cable is still connected + WRITE_LOG(LOG_WARN, "Hostside softreset to restart daemon, old sessionId:%u", sessionId); + daemon->PushAsyncMessage(sessionId, ASYNC_FREE_SESSION, nullptr, 0); +} + +// Prevent other USB data misfortunes to send the program crash +int HdcDaemonUSB::AvailablePacket(uint8_t *ioBuf, uint32_t *sessionId) +{ + int ret = RET_SUCCESS; + constexpr auto maxBufFactor = 1.2; + while (true) { + struct USBHead *usbPayloadHeader = (struct USBHead *)ioBuf; + if (memcmp(usbPayloadHeader->flag, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { + ret = ERR_BUF_CHECK; + break; + } + if (usbPayloadHeader->dataSize > MAX_SIZE_IOBUF * maxBufFactor + sizeof(USBHead)) { + ret = ERR_BUF_SIZE; + break; + } + if ((usbPayloadHeader->option & USB_OPTION_RESET)) { + ResetOldSession(usbPayloadHeader->sessionId); + ret = ERR_IO_SOFT_RESET; + break; + } + *sessionId = usbPayloadHeader->sessionId; + break; + } + return ret; +} + +// Work in subcrete,Work thread is ready +bool HdcDaemonUSB::ReadyForWorkThread(HSession hSession) +{ + HdcUSBBase::ReadyForWorkThread(hSession); + return true; +}; + +int HdcDaemonUSB::CloseBulkEp(bool bulkInOut, int bulkFd, uv_loop_t *loop) +{ + struct CtxCloseBulkEp { + uv_fs_t req; + HdcDaemonUSB *thisClass; + bool bulkInOut; + }; + CtxCloseBulkEp *ctx = new CtxCloseBulkEp(); + uv_fs_t *req = &ctx->req; + req->data = ctx; + ctx->bulkInOut = bulkInOut; + ctx->thisClass = this; + isAlive = false; + uv_fs_close(loop, req, bulkFd, [](uv_fs_t *req) { + auto ctx = (CtxCloseBulkEp *)req->data; + if (ctx->bulkInOut) { + ctx->thisClass->usbHandle.bulkIn = 0; + } else { + ctx->thisClass->usbHandle.bulkOut = 0; + } + WRITE_LOG(LOG_DEBUG, "Try to abort blukin write callback %s", ctx->bulkInOut ? "bulkin" : "bulkout"); + uv_fs_req_cleanup(req); + delete ctx; + }); + return 0; +} + +int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t *data, const int length) +{ + int bulkIn = hMainUSB->bulkIn; + int childRet = 0; + int ret = ERR_IO_FAIL; + int offset = 0; + while (modRunning && isAlive && !hSession->isDead && !hSession->hUSB->resetIO) { + childRet = write(bulkIn, (uint8_t *)data + offset, length - offset); + if (childRet <= 0) { + int err = errno; + if (err == EINTR) { + WRITE_LOG(LOG_DEBUG, "BulkinWrite write EINTR, try again"); + continue; + } else { + WRITE_LOG(LOG_FATAL, "BulkinWrite write fatal errno %d", err); + isAlive = false; + } + break; + } + offset += childRet; + if (offset >= length) { + break; + } + } + if (offset == length) { + ret = length; + } else { + WRITE_LOG(LOG_FATAL, + "BulkinWrite write failed, nsize:%d really:%d modRunning:%d isAlive:%d SessionDead:%d usbReset:%d", + length, offset, modRunning, isAlive, hSession->isDead, hSession->hUSB->resetIO); + } + USBHead *pUSBHead = (USBHead *)data; + if ((pUSBHead->option & USB_OPTION_TAIL) || ret < 0) { + // tail or failed, dec Ref + hSession->sendRef--; + } + return ret; +} + +int HdcDaemonUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) +{ + HdcDaemon *daemon = (HdcDaemon *)hSession->classInstance; + // Prevent memory stacking, send temporary way to use asynchronous + // Generally sent in the same thread, but when new session is created, there is a possibility that the old session + // is not retired. + // At present, the radical transmission method is currently opened directly in various threads, and + // it can be used exclusive File-DESC transmission mode in each thread. The late stage can be used as asynchronous + + // SendPipe to the main thread transmission. + uv_mutex_lock(&sendEP); + int ret = SendUSBIOSync(hSession, &usbHandle, data, length); + if (ret < 0) { + daemon->FreeSession(hSession->sessionId); + WRITE_LOG(LOG_DEBUG, "SendUSBRaw try to freesession"); + } + uv_mutex_unlock(&sendEP); + return ret; +} + +// cross thread call +void HdcDaemonUSB::OnNewHandshakeOK(const uint32_t sessionId) +{ + currentSessionId = sessionId; // real Id +} + +HSession HdcDaemonUSB::PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, int recvBytesIO) +{ + HdcDaemon *daemon = reinterpret_cast(clsMainBase); + HSession hChildSession = daemon->MallocSession(false, CONN_USB, this, sessionId); + if (!hChildSession) { + return nullptr; + } + if (currentSessionId != 0) { + // reset old session + // The Host side is restarted, but the USB cable is still connected + WRITE_LOG(LOG_WARN, "New session coming, restart old sessionId:%u", currentSessionId); + daemon->PushAsyncMessage(currentSessionId, ASYNC_FREE_SESSION, nullptr, 0); + } + Base::StartWorkThread(&daemon->loopMain, daemon->SessionWorkThread, Base::FinishWorkThread, hChildSession); + auto funcNewSessionUp = [](uv_timer_t *handle) -> void { + HSession hChildSession = reinterpret_cast(handle->data); + HdcDaemon *daemon = reinterpret_cast(hChildSession->classInstance); + if (hChildSession->childLoop.active_handles == 0) { + return; + } + if (!hChildSession->isDead) { + auto ctrl = daemon->BuildCtrlString(SP_START_SESSION, 0, nullptr, 0); + Base::SendToStream((uv_stream_t *)&hChildSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); + WRITE_LOG(LOG_DEBUG, "Main thread usbio mirgate finish"); + } + Base::TryCloseHandle(reinterpret_cast(handle), Base::CloseTimerCallback); + }; + Base::TimerUvTask(&daemon->loopMain, hChildSession, funcNewSessionUp); + return hChildSession; +} + +int HdcDaemonUSB::DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBuf, int readBytes) +{ + // Format:USBPacket1 payload1...USBPacketn + // payloadn-[USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] + HSession hChildSession = nullptr; + HdcDaemon *daemon = reinterpret_cast(clsMainBase); + hChildSession = daemon->AdminSession(OP_QUERY, sessionId, nullptr); + if (!hChildSession) { + hChildSession = PrepareNewSession(sessionId, readBuf, readBytes); + if (!hChildSession) { + return ERR_SESSION_NOFOUND; + } + } + if (hChildSession->childCleared) { + return ERR_SESSION_DEAD; + } + if (SendToHdcStream(hChildSession, reinterpret_cast(&hChildSession->dataPipe[STREAM_MAIN]), readBuf, + readBytes) + != RET_SUCCESS) { + return ERR_IO_FAIL; + } + return readBytes; +} + +bool HdcDaemonUSB::JumpAntiquePacket(const uint8_t &buf, ssize_t bytes) const +{ + constexpr size_t antiqueFlagSize = 4; + constexpr size_t antiqueFullSize = 24; + // anti CNXN 0x4e584e43 + uint8_t flag[] = { 0x43, 0x4e, 0x58, 0x4e }; + if (bytes == antiqueFullSize && !memcmp(&buf, flag, antiqueFlagSize)) { + return true; + } + return false; +} + +// Only physically swap EP ports will be reset +void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) +{ // Only read at the main thread + auto ctxIo = reinterpret_cast(req->data); + auto hUSB = reinterpret_cast(ctxIo->data); + auto thisClass = reinterpret_cast(ctxIo->thisClass); + uint8_t *bufPtr = ctxIo->buf; + ssize_t bytesIOBytes = req->result; + uint32_t sessionId = 0; + bool ret = false; + int childRet = 0; + --thisClass->ref; + while (thisClass->isAlive) { + // Don't care is module running, first deal with this + if (bytesIOBytes < 0) { + WRITE_LOG(LOG_WARN, "USBIO failed1 %s", uv_strerror(bytesIOBytes)); + break; + } else if (bytesIOBytes == 0) { + // zero packet + ret = true; + break; + } + if (thisClass->JumpAntiquePacket(*bufPtr, bytesIOBytes)) { + WRITE_LOG(LOG_DEBUG, "JumpAntiquePacket auto jump"); + ret = true; + break; + } + // guess is head of packet + if ((childRet = thisClass->AvailablePacket((uint8_t *)bufPtr, &sessionId)) != RET_SUCCESS) { + if (childRet != ERR_IO_SOFT_RESET) { + WRITE_LOG(LOG_WARN, "AvailablePacket check failed, ret:%d buf:%-50s", bytesIOBytes, bufPtr); + break; + } + // reset packet + } else { + // AvailablePacket case + if (thisClass->DispatchToWorkThread(sessionId, bufPtr, bytesIOBytes) < 0) { + WRITE_LOG(LOG_FATAL, "DispatchToWorkThread failed"); + break; + } + } + if (thisClass->LoopUSBRead(hUSB) < 0) { + WRITE_LOG(LOG_FATAL, "LoopUSBRead failed"); + break; + } + ret = true; + break; + } + if (!ret) { + thisClass->isAlive = false; + } + delete[] ctxIo->buf; + uv_fs_req_cleanup(req); + delete ctxIo; +} + +int HdcDaemonUSB::LoopUSBRead(HUSB hUSB) +{ + int ret = -1; + HdcDaemon *daemon = reinterpret_cast(clsMainBase); + // must > available size, or it will be incorrect + int readMax = Base::GetMaxBufSize() + sizeof(USBHead) + EXTRA_ALLOC_SIZE; + auto ctxIo = new CtxUvFileCommonIo(); + auto buf = new uint8_t[readMax](); + uv_fs_t *req = nullptr; + uv_buf_t iov; + if (ctxIo == nullptr || buf == nullptr) { + goto FAILED; + } + ctxIo->buf = buf; + ctxIo->bufSize = readMax; + ctxIo->data = hUSB; + ctxIo->thisClass = this; + req = &ctxIo->req; + req->data = ctxIo; + iov = uv_buf_init(reinterpret_cast(ctxIo->buf), ctxIo->bufSize); + ret = uv_fs_read(&daemon->loopMain, req, hUSB->bulkOut, &iov, 1, -1, OnUSBRead); + if (ret < 0) { + WRITE_LOG(LOG_FATAL, "uv_fs_read < 0"); + goto FAILED; + } + ++this->ref; + return 0; +FAILED: + if (ctxIo != nullptr) { + delete ctxIo; + } + if (buf != nullptr) { + delete[] buf; + } + return -1; +} + +// Because USB can connect to only one host,daemonUSB is only one Session by default +void HdcDaemonUSB::WatchEPTimer(uv_timer_t *handle) +{ + HdcDaemonUSB *thisClass = (HdcDaemonUSB *)handle->data; + HUSB hUSB = &thisClass->usbHandle; + HdcDaemon *daemon = reinterpret_cast(thisClass->clsMainBase); + if (thisClass->isAlive || thisClass->ref > 0) { + return; + } + bool resetEp = false; + do { + if (hUSB->bulkIn > 0) { + thisClass->CloseBulkEp(true, thisClass->usbHandle.bulkIn, &daemon->loopMain); + resetEp = true; + } + if (hUSB->bulkOut > 0) { + thisClass->CloseBulkEp(false, thisClass->usbHandle.bulkOut, &daemon->loopMain); + resetEp = true; + } + if (thisClass->controlEp > 0) { + close(thisClass->controlEp); + thisClass->controlEp = 0; + resetEp = true; + } + } while (false); + if (resetEp || thisClass->usbHandle.bulkIn != 0 || thisClass->usbHandle.bulkOut != 0) { + return; + } + // until all bulkport reset + if (thisClass->ConnectEPPoint(hUSB) != RET_SUCCESS) { + return; + } + // connect OK + thisClass->isAlive = true; + thisClass->LoopUSBRead(hUSB); +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/daemon/daemon_usb.h b/services/flashd/daemon/daemon_usb.h new file mode 100755 index 00000000..38dc5244 --- /dev/null +++ b/services/flashd/daemon/daemon_usb.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_DAEMON_USB_H +#define HDC_DAEMON_USB_H +#include "daemon_common.h" + +namespace Hdc { +class HdcDaemonUSB : public HdcUSBBase { +public: + HdcDaemonUSB(const bool serverOrDaemonIn, void *ptrMainBase); + virtual ~HdcDaemonUSB(); + int Initial(); + void Stop(); + int SendUSBRaw(HSession hSession, uint8_t *data, const int length); + void OnNewHandshakeOK(const uint32_t sessionId); + +private: + struct CtxUvFileCommonIo { + uv_fs_t req; + uint8_t *buf; + int bufSize; + void *thisClass; + void *data; + }; + static void OnUSBRead(uv_fs_t *req); + static void WatchEPTimer(uv_timer_t *handle); + int ConnectEPPoint(HUSB hUSB); + int DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBuf, int readBytes); + int AvailablePacket(uint8_t *ioBuf, uint32_t *sessionId); + void CloseEndpoint(HUSB hUSB, bool closeCtrlEp = false); + string GetDevPath(const std::string &path); + bool ReadyForWorkThread(HSession hSession); + int LoopUSBRead(HUSB hUSB); + HSession PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, int recvBytesIO); + bool JumpAntiquePacket(const uint8_t &buf, ssize_t bytes) const; + int SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t *data, const int length); + int CloseBulkEp(bool bulkInOut, int bulkFd, uv_loop_t *loop); + void ResetOldSession(const uint32_t sessionId); + + HdcUSB usbHandle; + string basePath; // usb device's base path + uint32_t currentSessionId = 0; // USB mode,limit only one session + std::atomic ref = 0; + uv_timer_t checkEP; // server-use + uv_mutex_t sendEP; + bool isAlive = false; + int controlEp = 0; // EP0 +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/daemon/flashd_main.cpp b/services/flashd/daemon/flashd_main.cpp index 18d8ebd6..56e801b8 100755 --- a/services/flashd/daemon/flashd_main.cpp +++ b/services/flashd/daemon/flashd_main.cpp @@ -24,13 +24,18 @@ int flashd_main(int argc, char **argv) std::vector args = updater::ParseParams(argc, argv); bool enableUsb = false; bool enableTcp = false; + WRITE_LOG(LOG_DEBUG, "flashd main run %d", argc); + const int size = 64; + char modeSet[size] = ""; + Base::GetHdcProperty("persist.hdc.mode", modeSet, size); + WRITE_LOG(LOG_DEBUG, "Background mode, persist.hdc.mode %s", modeSet); for (std::string arg : args) { if (arg.find("-l") != std::string::npos) { int logLevel = atoi(arg.c_str() + strlen("-l")); FLASHDAEMON_CHECK(!(logLevel < 0 || logLevel > LOG_LAST), logLevel = LOG_LAST, "Loglevel error %d", logLevel); Base::SetLogLevel(logLevel); - } else if (arg.find("-t") != std::string::npos) { + } else if (arg.find("-t") != std::string::npos || strncmp(modeSet, "tcp", 3) == 0) { // 3 tcp enableTcp = true; } else if (arg.find("-u") != std::string::npos) { enableUsb = true; @@ -41,8 +46,6 @@ int flashd_main(int argc, char **argv) Base::PrintMessage("Both TCP and USB are disable, default enable usb"); enableUsb = true; } - - WRITE_LOG(LOG_DEBUG, "flashd main run"); HdcDaemon daemon(false); daemon.InitMod(enableTcp, enableUsb); #ifndef UPDATER_UT diff --git a/services/flashd/daemon/jdwp.cpp b/services/flashd/daemon/jdwp.cpp new file mode 100755 index 00000000..7a3b1526 --- /dev/null +++ b/services/flashd/daemon/jdwp.cpp @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "jdwp.h" + +namespace Hdc { +HdcJdwp::HdcJdwp(uv_loop_t *loopIn) +{ + Base::ZeroStruct(listenPipe); + listenPipe.data = this; + loop = loopIn; + refCount = 0; + uv_rwlock_init(&lockMapContext); +} + +HdcJdwp::~HdcJdwp() +{ + uv_rwlock_destroy(&lockMapContext); +} + +bool HdcJdwp::ReadyForRelease() +{ + return refCount == 0; +} + +void HdcJdwp::Stop() +{ + auto funcListenPipeClose = [](uv_handle_t *handle) -> void { + HdcJdwp *thisClass = (HdcJdwp *)handle->data; + --thisClass->refCount; + }; + Base::TryCloseHandle((const uv_handle_t *)&listenPipe, funcListenPipeClose); + for (auto &&obj : mapCtxJdwp) { + HCtxJdwp v = obj.second; + FreeContext(v); + } + AdminContext(OP_CLEAR, 0, nullptr); +} + +void *HdcJdwp::MallocContext() +{ + HCtxJdwp ctx = nullptr; + if ((ctx = new ContextJdwp()) == nullptr) { + return nullptr; + } + ctx->thisClass = this; + ctx->pipe.data = ctx; + ++refCount; + return ctx; +} + +// Single thread, two parameters can be used +void HdcJdwp::FreeContext(HCtxJdwp ctx) +{ + if (ctx->finish) { + return; + } + Base::TryCloseHandle((const uv_handle_t *)&ctx->pipe); + ctx->finish = true; + AdminContext(OP_REMOVE, ctx->pid, nullptr); + auto funcReqClose = [](uv_idle_t *handle) -> void { + HCtxJdwp ctx = (HCtxJdwp)handle->data; + --ctx->thisClass->refCount; + Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseIdleCallback); + delete ctx; + }; + Base::IdleUvTask(loop, ctx, funcReqClose); +} + +void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) +{ + bool ret = true; + HCtxJdwp ctxJdwp = (HCtxJdwp)pipe->data; + HdcJdwp *thisClass = (HdcJdwp *)ctxJdwp->thisClass; + char *p = ctxJdwp->buf; + uint32_t pid = 0; + + if (nread == UV_ENOBUFS) { // It is definite enough, usually only 4 bytes + ret = false; + WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream IOBuf max"); + } else if (nread == 0) { + return; + } else if (nread < 0 || nread != 4) { // 4 : 4 bytes + ret = false; + WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream program exit pid:%d", ctxJdwp->pid); + } + if (ret) { + pid = atoi(p); + if (pid > 0) { + WRITE_LOG(LOG_DEBUG, "JDWP accept pid:%d", pid); + ctxJdwp->pid = pid; + thisClass->AdminContext(OP_ADD, pid, ctxJdwp); + ret = true; + } + } + Base::ZeroArray(ctxJdwp->buf); + if (!ret) { + thisClass->FreeContext(ctxJdwp); + } +} + +void HdcJdwp::AcceptClient(uv_stream_t *server, int status) +{ + uv_pipe_t *listenPipe = (uv_pipe_t *)server; + HdcJdwp *thisClass = (HdcJdwp *)listenPipe->data; + HCtxJdwp ctxJdwp = (HCtxJdwp)thisClass->MallocContext(); + if (!ctxJdwp) { + return; + } + uv_pipe_init(thisClass->loop, &ctxJdwp->pipe, 1); + if (uv_accept(server, (uv_stream_t *)&ctxJdwp->pipe) < 0) { + WRITE_LOG(LOG_DEBUG, "uv_accept failed"); + thisClass->FreeContext(ctxJdwp); + return; + } + auto funAlloc = [](uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf) -> void { + HCtxJdwp ctxJdwp = (HCtxJdwp)handle->data; + buf->base = (char *)ctxJdwp->buf ; + buf->len = sizeof(ctxJdwp->buf); + }; + uv_read_start((uv_stream_t *)&ctxJdwp->pipe, funAlloc, ReadStream); +} + +// Test bash connnet(UNIX-domain sockets):nc -U path/jdwp-control < hexpid.file +// Test uv connect(pipe): 'uv_pipe_connect' +bool HdcJdwp::JdwpListen() +{ +#ifdef HDC_PCDEBUG + // if test, canbe enable + return true; + const char jdwpCtrlName[] = { 'j', 'd', 'w', 'p', '-', 'c', 'o', 'n', 't', 'r', 'o', 'l', 0 }; + unlink(jdwpCtrlName); +#else + const char jdwpCtrlName[] = { '\0', 'j', 'd', 'w', 'p', '-', 'c', 'o', 'n', 't', 'r', 'o', 'l', 0 }; +#endif + const int DEFAULT_BACKLOG = 4; + bool ret = false; + while (true) { + uv_pipe_init(loop, &listenPipe, 0); + listenPipe.data = this; + if ((uv_pipe_bind(&listenPipe, jdwpCtrlName))) { + WRITE_LOG(LOG_WARN, "Bind error : %d: %s", errno, strerror(errno)); + return 1; + } + if (uv_listen((uv_stream_t *)&listenPipe, DEFAULT_BACKLOG, AcceptClient)) { + break; + } + ++refCount; + ret = true; + break; + } + // listenPipe close by stop + return ret; +} + +// Working in the main thread, but will be accessed by each session thread, so we need to set thread lock +void *HdcJdwp::AdminContext(const uint8_t op, const uint32_t pid, HCtxJdwp ctxJdwp) +{ + HCtxJdwp hRet = nullptr; + switch (op) { + case OP_ADD: { + uv_rwlock_wrlock(&lockMapContext); + mapCtxJdwp[pid] = ctxJdwp; + uv_rwlock_wrunlock(&lockMapContext); + break; + } + case OP_REMOVE: + uv_rwlock_wrlock(&lockMapContext); + mapCtxJdwp.erase(pid); + uv_rwlock_wrunlock(&lockMapContext); + break; + case OP_QUERY: { + uv_rwlock_rdlock(&lockMapContext); + if (mapCtxJdwp.count(pid)) { + hRet = mapCtxJdwp[pid]; + } + uv_rwlock_rdunlock(&lockMapContext); + break; + } + case OP_CLEAR: { + uv_rwlock_wrlock(&lockMapContext); + mapCtxJdwp.clear(); + uv_rwlock_wrunlock(&lockMapContext); + break; + } + default: + break; + } + return hRet; +} + +// work on main thread +void HdcJdwp::SendCallbackJdwpNewFD(uv_write_t *req, int status) +{ + // It usually works successful, not notify session work + HCtxJdwp ctx = (HCtxJdwp)req->data; + if (status >= 0) { + WRITE_LOG(LOG_DEBUG, "SendCallbackJdwpNewFD successful %d, active jdwp forward", ctx->pid); + } else { + WRITE_LOG(LOG_WARN, "SendCallbackJdwpNewFD failed %d", ctx->pid); + } + // close my process's fd + Base::TryCloseHandle((const uv_handle_t *)&ctx->jvmTCP); + delete req; + --ctx->thisClass->refCount; +} + +// Each session calls the interface through the main thread message queue, which cannot be called directly across +// threads +// work on main thread +bool HdcJdwp::SendJdwpNewFD(uint32_t targetPID, int fd) +{ + bool ret = false; + while (true) { + HCtxJdwp ctx = (HCtxJdwp)AdminContext(OP_QUERY, targetPID, nullptr); + if (!ctx) { + break; + } + ctx->dummy = (uint8_t)'!'; + if (uv_tcp_init(loop, &ctx->jvmTCP)) { + break; + } + if (uv_tcp_open(&ctx->jvmTCP, fd)) { + break; + } + // transfer fd to jvm + // clang-format off + if (Base::SendToStreamEx((uv_stream_t *)&ctx->pipe, (uint8_t *)&ctx->dummy, 1, (uv_stream_t *)&ctx->jvmTCP, + (void *)SendCallbackJdwpNewFD, (const void *)ctx) < 0) { + break; + } + // clang-format on + ++refCount; + ret = true; + WRITE_LOG(LOG_DEBUG, "SendJdwpNewFD successful targetPID:%d fd%d", targetPID, fd); + break; + } + return ret; +} + +// cross thread call begin +bool HdcJdwp::CheckPIDExist(uint32_t targetPID) +{ + HCtxJdwp ctx = (HCtxJdwp)AdminContext(OP_QUERY, targetPID, nullptr); + return ctx != nullptr; +} + +string HdcJdwp::GetProcessList() +{ + string ret; + uv_rwlock_rdlock(&lockMapContext); + for (auto &&v : mapCtxJdwp) { + ret += std::to_string(v.first) + "\n"; + } + uv_rwlock_rdunlock(&lockMapContext); + return ret; +} +// cross thread call finish + +// jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8000 +int HdcJdwp::Initial() +{ + if (!JdwpListen()) { + return ERR_MODULE_JDWP_FAILED; + } + return RET_SUCCESS; +} +} \ No newline at end of file diff --git a/services/flashd/daemon/jdwp.h b/services/flashd/daemon/jdwp.h new file mode 100755 index 00000000..93b3b902 --- /dev/null +++ b/services/flashd/daemon/jdwp.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_JDWP_H +#define HDC_JDWP_H +#include "daemon_common.h" + +namespace Hdc { +class HdcJdwp { +public: + HdcJdwp(uv_loop_t *loopIn); + virtual ~HdcJdwp(); + int Initial(); + void Stop(); + bool ReadyForRelease(); + + string GetProcessList(); + bool SendJdwpNewFD(uint32_t targetPID, int fd); + bool CheckPIDExist(uint32_t targetPID); + +private: + struct ContextJdwp { + uint32_t pid; + uv_pipe_t pipe; + HdcJdwp *thisClass; + bool finish; + char buf[sizeof(uint32_t)]; + uint8_t dummy; + uv_tcp_t jvmTCP; + }; + using HCtxJdwp = struct ContextJdwp *; + + bool JdwpListen(); + static void AcceptClient(uv_stream_t *server, int status); + static void ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf); + static void SendCallbackJdwpNewFD(uv_write_t *req, int status); + void *MallocContext(); + void FreeContext(HCtxJdwp ctx); + void *AdminContext(const uint8_t op, const uint32_t pid, HCtxJdwp ctxJdwp); + + uv_loop_t *loop; + uv_pipe_t listenPipe; + uint32_t refCount; + map mapCtxJdwp; + uv_rwlock_t lockMapContext; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/daemon/main.cpp b/services/flashd/daemon/main.cpp new file mode 100755 index 00000000..fcd82e87 --- /dev/null +++ b/services/flashd/daemon/main.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "daemon_common.h" +using namespace Hdc; + +static bool g_enableUsb = false; +static bool g_enableTcp = false; +static bool g_rootRun = false; +static bool g_backgroundRun = false; +namespace Hdc { +bool RestartDaemon(bool forkchild) +{ + char path[256] = ""; + size_t nPathSize = 256; + uv_exepath(path, &nPathSize); + execl(path, "hdcd", forkchild ? "-forkchild" : nullptr, nullptr); + return true; +} + +bool ForkChildCheck(int argc, const char *argv[]) +{ + // hdcd #service start forground + // hdcd -b #service start backgroundRun + // hdcd -fork #fork + char modeSet[BUF_SIZE_TINY] = ""; + Base::GetHdcProperty("persist.hdc.mode", modeSet, BUF_SIZE_TINY); + Base::PrintMessage("Background mode, persist.hdc.mode"); + string workMode = modeSet; + workMode = Base::Trim(workMode); + if (workMode == CMDSTR_TMODE_TCP) { + WRITE_LOG(LOG_DEBUG, "Property enable TCP"); + g_enableTcp = true; + } else if (workMode == CMDSTR_TMODE_USB) { + WRITE_LOG(LOG_DEBUG, "Property enable USB"); + g_enableUsb = true; + } else if (workMode == "all") { + WRITE_LOG(LOG_DEBUG, "Property enable USB and TCP"); + g_enableUsb = true; + g_enableTcp = true; + } else { + WRITE_LOG(LOG_DEBUG, "Default USB mode"); + g_enableUsb = true; + } + if (argc == CMD_ARG1_COUNT) { + if (!strcmp(argv[1], "-forkchild")) { + g_backgroundRun = false; // forkchild,Forced foreground + } else if (!strcmp(argv[1], "-b")) { + g_backgroundRun = true; + } + } + return true; +} + +int BackgroundRun() +{ + pid_t pc = fork(); // create process as daemon process + if (pc < 0) { + return -1; + } else if (!pc) { + int i; + const int MAX_NUM = 64; + for (i = 0; i < MAX_NUM; ++i) { + close(i); + } + RestartDaemon(true); + } else { // >0 orig process + } + return 0; +} + +string DaemonUsage() +{ + string ret; + ret = "\n Harmony device connector daemon(HDCD) Usage: hdcd [options]...\n\n" + "\n" + "general options:\n" + " -h - Print help\n" + " -l 0-5 - Print runtime log\n" + "\n" + "daemon mode options:\n" + " -b - Daemon run in background/fork mode\n" + " -u - Enable USB mode\n" + " -t - Enable TCP mode\n"; + return ret; +} + +bool GetDaemonCommandlineOptions(int argc, const char *argv[]) +{ + int ch; + // hdcd -l4 ... + WRITE_LOG(LOG_DEBUG, "Fgcli mode"); + // Both settings are running with parameters + while ((ch = getopt(argc, (char *const *)argv, "utl:")) != -1) { + switch (ch) { + case 'l': { + int logLevel = atoi(optarg); + if (logLevel < 0 || logLevel > LOG_LAST) { + WRITE_LOG(LOG_DEBUG, "Loglevel error!\n"); + return -1; + } + Base::SetLogLevel(logLevel); + break; + } + case 'u': { + Base::PrintMessage("Option USB enabled"); + g_enableUsb = true; + break; + } + case 't': { + Base::PrintMessage("Option TCP enabled"); + g_enableTcp = true; + break; + } + default: + Base::PrintMessage("Option:%c non-supported!", ch); + exit(0); + break; + } + } + return true; +} + +void NeedDropPriv() +{ + char droprootSet[BUF_SIZE_TINY] = ""; + Base::GetHdcProperty("persist.hdc.root", droprootSet, BUF_SIZE_TINY); + droprootSet[sizeof(droprootSet) - 1] = '\0'; + string rootMode = droprootSet; + if (Base::Trim(rootMode) == "1") { + setuid(0); + g_rootRun = true; + WRITE_LOG(LOG_DEBUG, "Root run"); + } else if (Base::Trim(rootMode) == "0") { + setuid(AID_SHELL); + } +} +} // namespace Hdc + +#ifndef UNIT_TEST +// daemon running with default behavior. options also can be given to custom its behavior including b/t/u/l etc. +int main(int argc, const char *argv[]) +{ + // check property + if (argc == 2 && !strcmp(argv[1], "-h")) { + string usage = DaemonUsage(); + fprintf(stderr, "%s", usage.c_str()); + return 0; + } + if (argc == CMD_ARG1_COUNT && !strcmp(argv[1], "-v")) { + string ver = Hdc::Base::GetVersion(); + fprintf(stderr, "%s\n", ver.c_str()); + return 0; + } + if (argc == 1 || (argc == CMD_ARG1_COUNT && (!strcmp(argv[1], "-forkchild") || !strcmp(argv[1], "-b")))) { + Base::SetLogLevel(LOG_LEVEL_FULL); + ForkChildCheck(argc, argv); + } else { + GetDaemonCommandlineOptions(argc, argv); + } + if (!g_enableTcp && !g_enableUsb) { + Base::PrintMessage("Both TCP and USB are disable, cannot run continue\n"); + return -1; + } + if (g_backgroundRun) { + return BackgroundRun(); + } + NeedDropPriv(); + umask(0); + signal(SIGPIPE, SIG_IGN); + signal(SIGCHLD, SIG_IGN); + WRITE_LOG(LOG_DEBUG, "HdcDaemon main run"); + HdcDaemon daemon(false); + daemon.InitMod(g_enableTcp, g_enableUsb); + daemon.WorkerPendding(); + bool wantRestart = daemon.WantRestart(); + WRITE_LOG(LOG_DEBUG, "Daemon finish"); + // There is no daemon, we can only restart myself. + if (g_rootRun && wantRestart) { + // just root can self restart, low privilege will be exit and start by service(root) + WRITE_LOG(LOG_INFO, "Daemon restart"); + RestartDaemon(false); + } + return 0; +} +#endif diff --git a/services/flashd/daemon/shell.cpp b/services/flashd/daemon/shell.cpp new file mode 100755 index 00000000..8a434221 --- /dev/null +++ b/services/flashd/daemon/shell.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "shell.h" +#include + +namespace Hdc { +std::mutex HdcShell::mutexPty; + +HdcShell::HdcShell(HTaskInfo hTaskInfo) + : HdcTaskBase(hTaskInfo) +{ + childShell = nullptr; + fdPTY = 0; +} + +HdcShell::~HdcShell() +{ + WRITE_LOG(LOG_DEBUG, "HdcShell deinit"); +}; + +bool HdcShell::ReadyForRelease() +{ + if (!HdcTaskBase::ReadyForRelease()) { + return false; + } + if (!childReady) { + return true; + } + if (!childShell->ReadyForRelease()) { + return false; + } + delete childShell; + childShell = nullptr; + if (fdPTY > 0) { + close(fdPTY); + } + return true; +} + +void HdcShell::StopTask() +{ + singalStop = true; + WRITE_LOG(LOG_DEBUG, "HdcShell::StopTask"); + if (!childReady) { + return; + } + if (childShell) { + childShell->StopWork(false, nullptr); + } + kill(pidShell, SIGKILL); + int status; + waitpid(pidShell, &status, 0); + WRITE_LOG(LOG_DEBUG, "StopTask, kill pidshell:%d", pidShell); +}; + +bool HdcShell::SpecialSignal(uint8_t ch) +{ + const uint8_t TXT_SIGNAL_ETX = 0x3; + bool ret = true; + switch (ch) { + case TXT_SIGNAL_ETX: { // Ctrl+C + pid_t tpgid = tcgetpgrp(fdPTY); + kill(tpgid, SIGINT); + break; + } + default: + ret = false; + break; + } + return ret; +} + +bool HdcShell::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + switch (command) { + case CMD_SHELL_INIT: { // initial + if (StartShell()) { + LogMsg(MSG_FAIL, "Shell initialize failed"); + } + break; + } + case CMD_SHELL_DATA: + if (!childReady) { + WRITE_LOG(LOG_DEBUG, "Shell not running"); + return false; + } + if (payloadSize == 1 && SpecialSignal(payload[0])) { + } else { + childShell->Write(payload, payloadSize); + } + break; + default: + break; + } + return true; +} + +int HdcShell::ChildForkDo(int pts, const char *cmd, const char *arg0, const char *arg1) +{ + dup2(pts, STDIN_FILENO); + dup2(pts, STDOUT_FILENO); + dup2(pts, STDERR_FILENO); + close(pts); + string text = "/proc/self/oom_score_adj"; + int fd = 0; + if ((fd = open(text.c_str(), O_WRONLY)) >= 0) { + write(fd, "0", 1); + close(fd); + } + char *env = nullptr; + if ((env = getenv("HOME")) && chdir(env) < 0) { + } + execl(cmd, cmd, arg0, arg1, nullptr); + _Exit(1); + return 0; +} + +int HdcShell::ShellFork(const char *cmd, const char *arg0, const char *arg1) +{ + pid_t pid; + pid = fork(); + if (pid < 0) { + WRITE_LOG(LOG_DEBUG, "Fork shell failed:%s", strerror(errno)); + return ERR_GENERIC; + } + if (pid == 0) { + HdcShell::mutexPty.unlock(); + setsid(); + close(ptm); + int pts = 0; + if ((pts = open(devname, O_RDWR | O_CLOEXEC)) < 0) { + return -1; + } + ChildForkDo(pts, cmd, arg0, arg1); + // proc finish + } else { + return pid; + } + return 0; +} + +int HdcShell::CreateSubProcessPTY(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) +{ + ptm = open(devPTMX.c_str(), O_RDWR | O_CLOEXEC); + if (ptm < 0) { + WRITE_LOG(LOG_DEBUG, "Cannot open ptmx, error:%s", strerror(errno)); + return ERR_FILE_OPEN; + } + if (grantpt(ptm) || unlockpt(ptm)) { + WRITE_LOG(LOG_DEBUG, "Cannot open2 ptmx, error:%s", strerror(errno)); + close(ptm); + return ERR_API_FAIL; + } + if (ptsname_r(ptm, devname, sizeof(devname)) != 0) { + WRITE_LOG(LOG_DEBUG, "Trouble with ptmx, error:%s", strerror(errno)); + close(ptm); + return ERR_API_FAIL; + } + *pid = ShellFork(cmd, arg0, arg1); + return ptm; +} + +bool HdcShell::FinishShellProc(const void *context, const bool result, const string exitMsg) +{ + WRITE_LOG(LOG_DEBUG, "FinishShellProc finish"); + HdcShell *thisClass = (HdcShell *)context; + thisClass->TaskFinish(); + --thisClass->refCount; + return true; +}; + +bool HdcShell::ChildReadCallback(const void *context, uint8_t *buf, const int size) +{ + HdcShell *thisClass = (HdcShell *)context; + return thisClass->SendToAnother(CMD_KERNEL_ECHO_RAW, (uint8_t *)buf, size); +}; + +int HdcShell::StartShell() +{ + WRITE_LOG(LOG_DEBUG, "StartShell..."); + int ret = 0; + HdcShell::mutexPty.lock(); + do { + if ((fdPTY = CreateSubProcessPTY(Base::GetShellPath().c_str(), "-", 0, &pidShell)) < 0) { + ret = ERR_PROCESS_SUB_FAIL; + break; + } + childShell = new HdcFileDescriptor(loopTask, fdPTY, this, ChildReadCallback, FinishShellProc); + if (!childShell->StartWork()) { + ret = ERR_API_FAIL; + break; + } + childReady = true; + ++refCount; + } while (false); + if (ret != RET_SUCCESS) { + if (pidShell > 0) { + kill(pidShell, SIGKILL); + } + // fdPTY close by ~clase + } + HdcShell::mutexPty.unlock(); + return ret; +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/daemon/shell.h b/services/flashd/daemon/shell.h new file mode 100755 index 00000000..1c2cda83 --- /dev/null +++ b/services/flashd/daemon/shell.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_SHELL_H +#define HDC_SHELL_H +#include "daemon_common.h" +#include + +namespace Hdc { +class HdcShell : public HdcTaskBase { +public: + HdcShell(HTaskInfo hTaskInfo); + virtual ~HdcShell(); + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); + void StopTask(); + bool ReadyForRelease(); + +private: + static bool FinishShellProc(const void *context, const bool result, const string exitMsg); + static bool ChildReadCallback(const void *context, uint8_t *buf, const int size); + int StartShell(); + int CreateSubProcessPTY(const char *cmd, const char *arg0, const char *arg1, pid_t *pid); + int ChildForkDo(int pts, const char *cmd, const char *arg0, const char *arg1); + bool SpecialSignal(uint8_t ch); + int ShellFork(const char *cmd, const char *arg0, const char *arg1); + + HdcFileDescriptor *childShell; + pid_t pidShell = 0; + int fdPTY; + int ptm = 0; + const string devPTMX = "/dev/ptmx"; + static std::mutex mutexPty; + char devname[BUF_SIZE_SMALL] = ""; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/daemon/usb_ffs.h b/services/flashd/daemon/usb_ffs.h new file mode 100755 index 00000000..1998daaf --- /dev/null +++ b/services/flashd/daemon/usb_ffs.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_USBFFS_H +#define HDC_USBFFS_H +// clang-format off +#include +#include "daemon_common.h" +// clang-format on + +namespace Hdc { +constexpr auto HDC_USBDR_SND = 0x0; +constexpr auto HDC_USBDR_RCV = 0x80; +constexpr auto HDC_USBMD_BLK = 0X02; +constexpr auto HDC_USBMD_RCV = 0X03; +constexpr auto HDC_CLASS = 0xff; +constexpr auto HDC_SUBCLASS = 0x50; +constexpr auto HDC_FSPKT_SIZE_MAX = 64; +constexpr auto HDC_HSPKT_SIZE_MAX = 512; +constexpr uint16_t HDC_SSPKT_SIZE_MAX = 1024; +constexpr auto USB_FFS_BASE = "/dev/usb-ffs/"; +constexpr auto HDC_USBTF_DEV = 0x01; +constexpr auto HDC_USBTF_CFG = 0x02; +constexpr auto HDC_USBTF_STR = 0x03; +constexpr auto HDC_USBTF_ITF = 0x04; +constexpr auto HDC_USBTF_EPS = 0x05; + +#define SHORT_LE(x) htole16(x) +#define LONG_LE(x) htole32(x) +#define HDC_INTERFACE_NAME "HDC Interface" + +struct UsbFunctionDesc { + struct usb_interface_descriptor ifDesc; + struct usb_endpoint_descriptor_no_audio from; + struct usb_endpoint_descriptor_no_audio to; +} __attribute__((packed)); + +static const struct { + struct usb_functionfs_strings_head head; + struct { + __le16 code; + const char name[sizeof(HDC_INTERFACE_NAME)]; + } __attribute__((packed)) firstItem; +} __attribute__((packed)) USB_FFS_VALUE = { + .head = + { + .magic = LONG_LE(FUNCTIONFS_STRINGS_MAGIC), + .length = LONG_LE(sizeof(USB_FFS_VALUE)), + .str_count = LONG_LE(1), + .lang_count = LONG_LE(1), + }, + .firstItem = + { + SHORT_LE(0x0409), + HDC_INTERFACE_NAME, + }, +}; + +struct UsbFunctionfsDescsHeadOld { + __le32 magic; + __le32 length; + __le32 config1Count; + __le32 config2Count; +} __attribute__((packed)); + +struct UsbFuncConfig { + struct usb_interface_descriptor ifDesc; + struct usb_endpoint_descriptor_no_audio from; + struct usb_ss_ep_comp_descriptor pairFrom; + struct usb_endpoint_descriptor_no_audio to; + struct usb_ss_ep_comp_descriptor pairTo; +} __attribute__((packed)); + +static struct UsbFuncConfig config3 = { + .ifDesc = { + .bLength = sizeof(config3.ifDesc), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 2, + .bInterfaceClass = HDC_CLASS, + .bInterfaceSubClass = HDC_SUBCLASS, + .bInterfaceProtocol = VER_PROTOCOL, + .iInterface = 1 + }, + .from = { + .bLength = sizeof(config3.from), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = HDC_SSPKT_SIZE_MAX, + }, + .pairFrom = { + .bLength = sizeof(config3.pairFrom), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + .bMaxBurst = 4, + }, + .to = { + .bLength = sizeof(config3.to), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = HDC_SSPKT_SIZE_MAX, + }, + .pairTo = { + .bLength = sizeof(config3.pairTo), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + .bMaxBurst = 4, + }, +}; + +static struct UsbFunctionDesc config1 = { + .ifDesc = { + .bLength = sizeof(config1.ifDesc), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 2, + .bInterfaceClass = HDC_CLASS, + .bInterfaceSubClass = HDC_SUBCLASS, + .bInterfaceProtocol = VER_PROTOCOL, + .iInterface = 1 + }, + .from = { + .bLength = sizeof(config1.from), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = HDC_FSPKT_SIZE_MAX, + }, + .to = { + .bLength = sizeof(config1.to), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = HDC_FSPKT_SIZE_MAX, + }, +}; + +static struct UsbFunctionDesc config2 = { + .ifDesc = { + .bLength = sizeof(config2.ifDesc), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 2, + .bInterfaceClass = HDC_CLASS, + .bInterfaceSubClass = HDC_SUBCLASS, + .bInterfaceProtocol = VER_PROTOCOL, + .iInterface = 1 + }, + .from = { + .bLength = sizeof(config2.from), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = HDC_HSPKT_SIZE_MAX, + }, + .to = { + .bLength = sizeof(config2.to), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = HDC_HSPKT_SIZE_MAX, + }, +}; + +static const struct { + struct usb_functionfs_descs_head_v2 head; + __le32 config1Count; + __le32 config2Count; + __le32 config3Count; + __le32 configWosCount; + struct UsbFunctionDesc config1Desc, config2Desc; + struct UsbFuncConfig config3Desc; + struct usb_os_desc_header wosHead; + struct usb_ext_compat_desc wosDesc; +} __attribute__((packed)) USB_FFS_DESC = { + .head = + { + .magic = LONG_LE(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), + .length = LONG_LE(sizeof(USB_FFS_DESC)), + .flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC | + FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC + }, + .config1Count = 3, + .config2Count = 3, + .config3Count = 5, + .configWosCount = 1, + .config1Desc = config1, + .config2Desc = config2, + .config3Desc = config3, + .wosHead = { + .interface = 1, + .dwLength = LONG_LE(sizeof(USB_FFS_DESC.wosHead) + sizeof(USB_FFS_DESC.wosDesc)), + .bcdVersion = SHORT_LE(1), + .wIndex = SHORT_LE(4), + .bCount = 1, + .Reserved = 0, + }, + .wosDesc = { + .bFirstInterfaceNumber = 0, + .Reserved1 = 1, + .CompatibleID = { 'W', 'I', 'N', 'U', 'S', 'B', '\0', '\0'}, + .SubCompatibleID = {0}, + .Reserved2 = {0}, + } +}; +} // namespace Hdc +#endif diff --git a/services/flashd/host/client.cpp b/services/flashd/host/client.cpp new file mode 100755 index 00000000..efefabc5 --- /dev/null +++ b/services/flashd/host/client.cpp @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "client.h" +#include "server.h" + +namespace Hdc { +HdcClient::HdcClient(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn) + : HdcChannelBase(serverOrClient, addrString, loopMainIn) +{ + MallocChannel(&channel); // free by logic + debugRetryCount = 0; +} + +HdcClient::~HdcClient() +{ +#ifndef _WIN32 + if (terminalChanged) { + tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminalState); + terminalChanged = false; + } +#endif + Base::TryCloseLoop(loopMain, "ExecuteCommand finish"); +} + +void HdcClient::NotifyInstanceChannelFree(HChannel hChannel) +{ + if (bShellInteractive) { + WRITE_LOG(LOG_DEBUG, "Restore tty"); + ModifyTty(false, &hChannel->stdinTty); + } +} + +uint32_t HdcClient::GetLastPID() +{ + char bufPath[BUF_SIZE_MEDIUM] = ""; + size_t size = BUF_SIZE_MEDIUM; + char pidBuf[BUF_SIZE_TINY] = ""; + // get running pid to kill it + if (uv_os_tmpdir(bufPath, &size) < 0) { + WRITE_LOG(LOG_FATAL, "Tmppath failed"); + return 0; + } + string path = Base::StringFormat("%s%c.%s.pid", bufPath, Base::GetPathSep(), SERVER_NAME.c_str()); + Base::ReadBinFile(path.c_str(), (void **)&pidBuf, BUF_SIZE_TINY); + int pid = atoi(pidBuf); // pid maybe 0 + return pid; +} + +bool HdcClient::StartKillServer(const char *cmd, bool startOrKill) +{ + bool isNowRunning = Base::ProgramMutex(SERVER_NAME.c_str(), true) != 0; + const int SIGN_NUM = 9; + uint32_t pid = GetLastPID(); + if (!pid) { + return false; + } + if (startOrKill) { + if (isNowRunning) { + // already running + if (!strstr(cmd, " -r")) { + return true; + } + if (pid) { + uv_kill(pid, SIGN_NUM); + } + } + HdcServer::PullupServer(channelHostPort.c_str()); + } else { + if (isNowRunning && pid) { + uv_kill(pid, SIGN_NUM); + Base::PrintMessage("Kill server finish"); + } + // already running + if (!strstr(cmd, " -r")) { + return true; + } + HdcServer::PullupServer(channelHostPort.c_str()); + } + return true; +} + +void HdcClient::DoCtrlServiceWork(uv_check_t *handle) +{ + HdcClient *thisClass = (HdcClient *)handle->data; + const char *cmd = thisClass->command.c_str(); + string &strCmd = thisClass->command; + while (true) { + if (!strncmp(cmd, CMDSTR_SERVICE_START.c_str(), CMDSTR_SERVICE_START.size())) { + thisClass->StartKillServer(cmd, true); + } else if (!strncmp(cmd, CMDSTR_SERVICE_KILL.c_str(), CMDSTR_SERVICE_KILL.size())) { + thisClass->StartKillServer(cmd, false); + // clang-format off + } else if (!strncmp(cmd, CMDSTR_GENERATE_KEY.c_str(), CMDSTR_GENERATE_KEY.size()) && + strCmd.find(" ") != std::string::npos) { + // clang-format on + string keyPath = strCmd.substr(CMDSTR_GENERATE_KEY.size() + 1, strCmd.size()); + HdcAuth::GenerateKey(keyPath.c_str()); + } else { + Base::PrintMessage("Unknow command"); + } + break; + } + Base::TryCloseHandle((const uv_handle_t *)handle); +} + +int HdcClient::CtrlServiceWork(const char *commandIn) +{ + command = commandIn; + ctrlServerWork.data = this; + uv_check_init(loopMain, &ctrlServerWork); + uv_check_start(&ctrlServerWork, DoCtrlServiceWork); + uv_run(loopMain, UV_RUN_NOWAIT); + return 0; +} + +string HdcClient::AutoConnectKey(string &doCommand, const string &preConnectKey) const +{ + string key = preConnectKey; + bool isNoTargetCommand = false; + vector vecNoConnectKeyCommand; + vecNoConnectKeyCommand.push_back(CMDSTR_SOFTWARE_VERSION); + vecNoConnectKeyCommand.push_back(CMDSTR_SOFTWARE_HELP); + vecNoConnectKeyCommand.push_back(CMDSTR_TARGET_DISCOVER); + vecNoConnectKeyCommand.push_back(CMDSTR_LIST_TARGETS); + vecNoConnectKeyCommand.push_back(CMDSTR_CONNECT_TARGET); + vecNoConnectKeyCommand.push_back(CMDSTR_KILL_SERVER); + vecNoConnectKeyCommand.push_back(CMDSTR_FORWARD_FPORT + " ls"); + vecNoConnectKeyCommand.push_back(CMDSTR_FORWARD_FPORT + " rm"); + for (string v : vecNoConnectKeyCommand) { + if (!doCommand.compare(0, v.size(), v)) { + isNoTargetCommand = true; + break; + } + } + if (isNoTargetCommand) { + key = ""; + } else { + if (!preConnectKey.size()) { + key = CMDSTR_CONNECT_ANY; + } + } + return key; +} + +int HdcClient::ExecuteCommand(const string &commandIn) +{ + char ip[BUF_SIZE_TINY] = ""; + uint16_t port = 0; + if (Base::ConnectKey2IPPort(channelHostPort.c_str(), ip, &port) < 0) { + return -1; + } + command = commandIn; + connectKey = AutoConnectKey(command, connectKey); + ConnectServerForClient(ip, port); + uv_timer_init(loopMain, &waitTimeDoCmd); + waitTimeDoCmd.data = this; + uv_timer_start(&waitTimeDoCmd, CommandWorker, 10, 10); + WorkerPendding(); + return 0; +} + +int HdcClient::Initial(const string &connectKeyIn) +{ + connectKey = connectKeyIn; + if (!channelHostPort.size() || !channelHost.size() || !channelPort) { + WRITE_LOG(LOG_FATAL, "Listen string initial failed"); + return ERR_PARM_FAIL; + } + return 0; +} + +int HdcClient::ConnectServerForClient(const char *ip, uint16_t port) +{ + if (uv_is_closing((const uv_handle_t *)&channel->hWorkTCP)) { + return ERR_SOCKET_FAIL; + } + WRITE_LOG(LOG_DEBUG, "Try to connect %s:%d", ip, port); + struct sockaddr_in dest; + uv_ip4_addr(ip, port, &dest); + uv_connect_t *conn = new uv_connect_t(); + conn->data = this; + uv_tcp_connect(conn, (uv_tcp_t *)&channel->hWorkTCP, (const struct sockaddr *)&dest, Connect); + return 0; +} + +void HdcClient::CommandWorker(uv_timer_t *handle) +{ + const uint16_t maxWaitRetry = 500; + HdcClient *thisClass = (HdcClient *)handle->data; + if (++thisClass->debugRetryCount > maxWaitRetry) { + uv_timer_stop(handle); + uv_stop(thisClass->loopMain); + WRITE_LOG(LOG_DEBUG, "Connect server failed"); + return; + } + if (!thisClass->channel->handshakeOK) { + return; + } + uv_timer_stop(handle); + WRITE_LOG(LOG_DEBUG, "Connect server successful"); + bool closeInput = false; + if (!HostUpdater::ConfirmCommand(thisClass->command, closeInput)) { + uv_timer_stop(handle); + uv_stop(thisClass->loopMain); + WRITE_LOG(LOG_DEBUG, "Cmd \'%s\' has been canceld", thisClass->command.c_str()); + return; + } + if (closeInput) { + thisClass->CloseInput(); + } + thisClass->Send(thisClass->channel->channelId, (uint8_t *)thisClass->command.c_str(), + thisClass->command.size() + 1); +} + +void HdcClient::AllocStdbuf(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) +{ + if (sizeWanted <= 0) { + return; + } + HChannel context = (HChannel)handle->data; + int availSize = strlen(context->bufStd); + buf->base = (char *)context->bufStd + availSize; + buf->len = sizeof(context->bufStd) - availSize - 2; // reserve 2bytes +} + +void HdcClient::ReadStd(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) +{ + HChannel hChannel = (HChannel)stream->data; + HdcClient *thisClass = (HdcClient *)hChannel->clsChannel; + char *command = hChannel->bufStd; + if (nread <= 0) { + return; // error + } + thisClass->Send(hChannel->channelId, (uint8_t *)command, strlen(command)); + Base::ZeroArray(hChannel->bufStd); +} + +void HdcClient::ModifyTty(bool setOrRestore, uv_tty_t *tty) +{ + if (setOrRestore) { +#ifdef _WIN32 + uv_tty_set_mode(tty, UV_TTY_MODE_RAW); +#else + CloseInput(); +#endif + } else { +#ifndef _WIN32 + tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminalState); + terminalChanged = false; +#endif + } +} + +void HdcClient::BindLocalStd(HChannel hChannel) +{ + if (command == CMDSTR_SHELL) { + bShellInteractive = true; + } + if (uv_guess_handle(STDIN_FILENO) != UV_TTY) { + WRITE_LOG(LOG_FATAL, "Not support std mode"); + return; + } + + WRITE_LOG(LOG_DEBUG, "Tty std mode"); + if (uv_tty_init(loopMain, &hChannel->stdoutTty, STDOUT_FILENO, 0) + || uv_tty_init(loopMain, &hChannel->stdinTty, STDIN_FILENO, 1)) { + WRITE_LOG(LOG_DEBUG, "uv_tty_init failed"); + return; + } + hChannel->stdoutTty.data = hChannel; + ++hChannel->uvRef; + hChannel->stdinTty.data = hChannel; + ++hChannel->uvRef; + if (bShellInteractive) { + WRITE_LOG(LOG_DEBUG, "uv_tty_init uv_tty_set_mode"); + ModifyTty(true, &hChannel->stdinTty); + uv_read_start((uv_stream_t *)&hChannel->stdinTty, AllocStdbuf, ReadStd); + } +} + +void HdcClient::Connect(uv_connect_t *connection, int status) +{ + HdcClient *thisClass = (HdcClient *)connection->data; + delete connection; + HChannel hChannel = (HChannel)thisClass->channel; + if (status < 0 || uv_is_closing((const uv_handle_t *)&hChannel->hWorkTCP)) { + WRITE_LOG(LOG_FATAL, "connect failed"); + thisClass->FreeChannel(hChannel->channelId); + return; + } + thisClass->BindLocalStd(hChannel); + Base::SetTcpOptions((uv_tcp_t *)&hChannel->hWorkTCP); + uv_read_start((uv_stream_t *)&hChannel->hWorkTCP, AllocCallback, ReadStream); +} + +int HdcClient::PreHandshake(HChannel hChannel, const uint8_t *buf) +{ + ChannelHandShake *hShake = (ChannelHandShake *)buf; + if (strncmp(hShake->banner, HANDSHAKE_MESSAGE.c_str(), HANDSHAKE_MESSAGE.size())) { + hChannel->availTailIndex = 0; + WRITE_LOG(LOG_DEBUG, "Channel Hello failed"); + return ERR_BUF_CHECK; + } + // sync remote session id to local + uint32_t unOld = hChannel->channelId; + hChannel->channelId = ntohl(hShake->channelId); + AdminChannel(OP_UPDATE, unOld, hChannel); + WRITE_LOG(LOG_DEBUG, "Client channel handshake finished, use connectkey:%s", connectKey.c_str()); + // send config + // channel handshake step2 + if (memset_s(hShake->connectKey, sizeof(hShake->connectKey), 0, sizeof(hShake->connectKey)) != EOK + || memcpy_s(hShake->connectKey, sizeof(hShake->connectKey), connectKey.c_str(), connectKey.size()) != EOK) { + hChannel->availTailIndex = 0; + WRITE_LOG(LOG_DEBUG, "Channel Hello failed"); + return ERR_BUF_COPY; + } + Send(hChannel->channelId, reinterpret_cast(hShake), sizeof(ChannelHandShake)); + hChannel->handshakeOK = true; +#ifdef HDC_CHANNEL_KEEP_ALIVE + // Evaluation method, non long-term support + Send(hChannel->channelId, reinterpret_cast(CMDSTR_INNER_ENABLE_KEEPALIVE.c_str()), + CMDSTR_INNER_ENABLE_KEEPALIVE.size()); +#endif + return RET_SUCCESS; +} + +// read serverForClient(server)TCP data +int HdcClient::ReadChannel(HChannel hChannel, uint8_t *buf, const int bytesIO) +{ + if (!hChannel->handshakeOK) { + return PreHandshake(hChannel, buf); + } +#ifdef UNIT_TEST + // Do not output to console when the unit test + return 0; +#endif + WRITE_LOG(LOG_DEBUG, "Client ReadChannel :%d", bytesIO); + string s(reinterpret_cast(buf), bytesIO); + fprintf(stdout, "%s", s.c_str()); + fflush(stdout); + return 0; +} + +void HdcClient::CloseInput() +{ +#ifndef _WIN32 + if (tcgetattr(STDIN_FILENO, &terminalState)) + return; + termios tio; + if (tcgetattr(STDIN_FILENO, &tio)) + return; + cfmakeraw(&tio); + tio.c_cc[VTIME] = 0; + tio.c_cc[VMIN] = 1; + tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio); + terminalChanged = true; +#endif +} +} // namespace Hdc diff --git a/services/flashd/host/client.h b/services/flashd/host/client.h new file mode 100755 index 00000000..3efc5700 --- /dev/null +++ b/services/flashd/host/client.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_CLIENT_H +#define HDC_CLIENT_H +#include "host_common.h" + +namespace Hdc { +class HdcClient : public HdcChannelBase { +public: + HdcClient(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn); + virtual ~HdcClient(); + int Initial(const string &connectKeyIn); + int ExecuteCommand(const string &commandIn); + int CtrlServiceWork(const char *commandIn); + void CloseInput(); +protected: +private: + static void DoCtrlServiceWork(uv_check_t *handle); + static void Connect(uv_connect_t *connection, int status); + static void AllocStdbuf(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf); + static void ReadStd(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); + static void CommandWorker(uv_timer_t *handle); + int ConnectServerForClient(const char *ip, uint16_t port); + int ReadChannel(HChannel hChannel, uint8_t *buf, const int bytesIO); + int PreHandshake(HChannel hChannel, const uint8_t *buf); + string AutoConnectKey(string &doCommand, const string &preConnectKey) const; + uint32_t GetLastPID(); + bool StartKillServer(const char *cmd, bool startOrKill); + void BindLocalStd(); + void BindLocalStd(HChannel hChannel); + void ModifyTty(bool setOrRestore, uv_tty_t *tty); + void NotifyInstanceChannelFree(HChannel hChannel); + +#ifndef _WIN32 + termios terminalState; + bool terminalChanged = false; +#endif + string connectKey; + string command; + uint16_t debugRetryCount; + bool bShellInteractive = false; + uv_timer_t waitTimeDoCmd; + uv_check_t ctrlServerWork; + HChannel channel; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/host/host_app.cpp b/services/flashd/host/host_app.cpp new file mode 100755 index 00000000..938af005 --- /dev/null +++ b/services/flashd/host/host_app.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "host_app.h" + +namespace Hdc { +HdcHostApp::HdcHostApp(HTaskInfo hTaskInfo) + : HdcTransferBase(hTaskInfo) +{ + commandBegin = CMD_APP_BEGIN; + commandData = CMD_APP_DATA; +} + +HdcHostApp::~HdcHostApp() +{ +} + +bool HdcHostApp::BeginInstall(CtxFile *context, const char *command) +{ + int argc = 0; + bool ret = false; + string options; + char **argv = Base::SplitCommandToArgs(command, &argc); + if (argc < 1) { + goto Finish; + } + + for (int i = 0; i < argc; ++i) { + if (!strcmp(argv[i], CMD_OPTION_CLIENTCWD.c_str())) { + if (i + 1 < argc) { + context->transferConfig.clientCwd = argv[i + 1]; + i += 1; // add content index + } + } else if (!strncmp(argv[i], "-", 1)) { + if (options.size()) { + options += " "; + } + options += argv[i]; + } else { + string path = argv[i]; + ExtractRelativePath(context->transferConfig.clientCwd, path); + if (MatchPackageExtendName(path, ".hap")) { + context->taskQueue.push_back(path); + } else { + GetSubFiles(argv[i], ".hap", &context->taskQueue); + } + } + } + if (!context->taskQueue.size()) { + LogMsg(MSG_FAIL, "Not any installation package was found"); + return false; + } + // remove repeate + sort(context->taskQueue.begin(), context->taskQueue.end()); + context->taskQueue.erase(unique(context->taskQueue.begin(), context->taskQueue.end()), context->taskQueue.end()); + + context->transferConfig.options = options; + context->transferConfig.functionName = CMDSTR_APP_INSTALL; + RunQueue(context); + ret = true; +Finish: + if (argv) { + delete[]((char *)argv); + } + return ret; +} + +bool HdcHostApp::BeginSideload(CtxFile *context, const char *localPath) +{ + bool ret = false; + context->transferConfig.functionName = CMDSTR_APP_SIDELOAD; + context->taskQueue.push_back(localPath); + RunQueue(context); + ret = true; + return ret; +} + +void HdcHostApp::RunQueue(CtxFile *context) +{ + ++refCount; + context->localPath = context->taskQueue.back(); + uv_fs_open(loopTask, &context->fsOpenReq, context->localPath.c_str(), O_RDONLY, 0, OnFileOpen); + context->master = true; +} + +void HdcHostApp::CheckMaster(CtxFile *context) +{ + uv_fs_t fs; + Base::ZeroStruct(fs.statbuf); + uv_fs_fstat(nullptr, &fs, context->fsOpenReq.result, nullptr); + context->transferConfig.fileSize = fs.statbuf.st_size; + uv_fs_req_cleanup(&fs); + + context->transferConfig.optionalName + = Base::GetRandomString(9); // Prevent the name of illegal APP leads to pm unable to install + if (context->localPath.find(".hap") != (size_t)-1) { + context->transferConfig.optionalName += ".hap"; + } else { + context->transferConfig.optionalName += ".bundle"; + } + string bufString = SerialStruct::SerializeToString(context->transferConfig); + SendToAnother(CMD_APP_CHECK, (uint8_t *)bufString.c_str(), bufString.size()); +} + +bool HdcHostApp::CheckInstallContinue(AppModType mode, bool lastResult, const char *msg) +{ + string modeDesc; + switch (mode) { + case APPMOD_INSTALL: + modeDesc = "App install"; + break; + case APPMOD_UNINSTALL: + modeDesc = "App uninstall"; + break; + case APPMOD_SIDELOAD: + modeDesc = "Side load"; + break; + default: + modeDesc = "Unknow"; + break; + } + ctxNow.taskQueue.pop_back(); + LogMsg(MSG_INFO, "%s path:%s, queuesize:%d, msg:%s", modeDesc.c_str(), ctxNow.localPath.c_str(), + ctxNow.taskQueue.size(), msg); + if (singalStop || !ctxNow.taskQueue.size()) { + LogMsg(MSG_OK, "AppMod finish"); + return false; + } + RunQueue(&ctxNow); + return true; +} + +bool HdcHostApp::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + if (!HdcTransferBase::CommandDispatch(command, payload, payloadSize)) { + return false; + } + bool ret = true; + constexpr int cmdOffset = 2; + switch (command) { + case CMD_APP_INIT: { + ret = BeginInstall(&ctxNow, (const char *)payload); + break; + } + case CMD_APP_FINISH: { + AppModType mode = (AppModType)payload[0]; + bool result = (bool)payload[1]; + string s(reinterpret_cast(payload + cmdOffset), payloadSize - cmdOffset); + ret = CheckInstallContinue(mode, result, s.c_str()); + break; + } + case CMD_APP_UNINSTALL: { + SendToAnother(CMD_APP_UNINSTALL, payload, payloadSize); + ctxNow.taskQueue.push_back(reinterpret_cast(payload)); // just compatible + break; + } + case CMD_APP_SIDELOAD: { + BeginSideload(&ctxNow, (const char *)payload); + break; + } + default: + break; + } + return ret; +}; +} \ No newline at end of file diff --git a/services/flashd/host/host_app.h b/services/flashd/host/host_app.h new file mode 100755 index 00000000..ad3c8845 --- /dev/null +++ b/services/flashd/host/host_app.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_HOST_APP_H +#define HDC_HOST_APP_H +#include "host_common.h" + +namespace Hdc { +class HdcHostApp : public HdcTransferBase { +public: + HdcHostApp(HTaskInfo hTaskInfo); + virtual ~HdcHostApp(); + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); + +private: + bool BeginInstall(CtxFile *context, const char *command); + void CheckMaster(CtxFile *context); + bool CheckInstallContinue(AppModType mode, bool lastResult, const char *msg); + void RunQueue(CtxFile *context); + bool BeginSideload(CtxFile *context, const char *localPath); +}; +} +#endif \ No newline at end of file diff --git a/services/flashd/host/host_common.h b/services/flashd/host/host_common.h new file mode 100755 index 00000000..e6be2ba5 --- /dev/null +++ b/services/flashd/host/host_common.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_HOST_COMMON_H +#define HDC_HOST_COMMON_H + +// clang-format off +#include "../common/common.h" +#include "../common/file.h" +#include "../common/transfer.h" +#include "../common/forward.h" +#include "../common/async_cmd.h" +#include "../common/serial_struct.h" + +#include "host_tcp.h" +#include "host_usb.h" +#include "translate.h" +#include "server_for_client.h" +#include "client.h" +#include "host_app.h" +#include "host_forward.h" +#include "host_unity.h" +#include "host_updater.h" +// clang-format on + +#endif \ No newline at end of file diff --git a/services/flashd/host/host_forward.cpp b/services/flashd/host/host_forward.cpp new file mode 100755 index 00000000..72cd3f83 --- /dev/null +++ b/services/flashd/host/host_forward.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "host_forward.h" + +namespace Hdc { +HdcHostForward::HdcHostForward(HTaskInfo hTaskInfo) + : HdcForwardBase(hTaskInfo) +{ +} + +HdcHostForward::~HdcHostForward() +{ +} +} \ No newline at end of file diff --git a/services/flashd/host/host_forward.h b/services/flashd/host/host_forward.h new file mode 100755 index 00000000..5c984106 --- /dev/null +++ b/services/flashd/host/host_forward.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_HOST_FORWARD_H +#define HDC_HOST_FORWARD_H +#include "host_common.h" + +namespace Hdc { +class HdcHostForward : public HdcForwardBase { +public: + HdcHostForward(HTaskInfo hTaskInfo); + virtual ~HdcHostForward(); + +private: +}; +} // namespace Hdc + +#endif \ No newline at end of file diff --git a/services/flashd/host/host_tcp.cpp b/services/flashd/host/host_tcp.cpp new file mode 100755 index 00000000..49463605 --- /dev/null +++ b/services/flashd/host/host_tcp.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "host_tcp.h" +#include "server.h" + +namespace Hdc { +HdcHostTCP::HdcHostTCP(const bool serverOrDaemonIn, void *ptrMainBase) + : HdcTCPBase(serverOrDaemonIn, ptrMainBase) +{ + broadcastFindWorking = false; +} + +HdcHostTCP::~HdcHostTCP() +{ + WRITE_LOG(LOG_DEBUG, "~HdcHostTCP"); +} + +void HdcHostTCP::Stop() +{ +} + +void HdcHostTCP::RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf) +{ + char bufString[BUF_SIZE_TINY]; + uint16_t port = 0; + char *p = strstr(rcvbuf->base, "-"); + if (!p) { + return; + } + port = atoi(p + 1); + if (!port) { + return; + } + uv_ip4_name((sockaddr_in *)addrSrc, bufString, sizeof(bufString)); + string addrPort = string(bufString); + addrPort += string(":") + std::to_string(port); + lstDaemonResult.push_back(addrPort); +} + +void HdcHostTCP::BroadcastTimer(uv_idle_t *handle) +{ + uv_stop(handle->loop); +} + +// Executive Administration Network Broadcast Discovery, broadcastLanIP==which interface to broadcast +void HdcHostTCP::BroadcatFindDaemon(const char *broadcastLanIP) +{ + if (broadcastFindWorking) { + return; + } + broadcastFindWorking = true; + lstDaemonResult.clear(); + + uv_loop_t loopBroadcast; + uv_loop_init(&loopBroadcast); + struct sockaddr_in addr; + uv_udp_send_t req; + uv_udp_t client; + // send + uv_ip4_addr(broadcastLanIP, 0, &addr); + uv_udp_init(&loopBroadcast, &client); + uv_udp_bind(&client, (const struct sockaddr *)&addr, 0); + uv_udp_set_broadcast(&client, 1); + uv_ip4_addr("255.255.255.255", DEFAULT_PORT, &addr); + uv_buf_t buf = uv_buf_init((char *)HANDSHAKE_MESSAGE.c_str(), HANDSHAKE_MESSAGE.size()); + uv_udp_send(&req, &client, &buf, 1, (const struct sockaddr *)&addr, nullptr); + // recv + uv_udp_t server; + server.data = this; + uv_ip4_addr(broadcastLanIP, DEFAULT_PORT, &addr); + uv_udp_init(&loopBroadcast, &server); + uv_udp_bind(&server, (const struct sockaddr *)&addr, UV_UDP_REUSEADDR); + uv_udp_recv_start(&server, AllocStreamUDP, RecvUDP); + // find timeout + uv_timer_t tLastCheck; + uv_timer_init(&loopBroadcast, &tLastCheck); + uv_timer_start(&tLastCheck, (uv_timer_cb)BroadcastTimer, TIME_BASE, 0); // timeout debug 1s + + uv_run(&loopBroadcast, UV_RUN_DEFAULT); + uv_loop_close(&loopBroadcast); + broadcastFindWorking = false; +} + +void HdcHostTCP::Connect(uv_connect_t *connection, int status) +{ + HSession hSession = (HSession)connection->data; + delete connection; + HdcSessionBase *ptrConnect = (HdcSessionBase *)hSession->classInstance; + auto ctrl = ptrConnect->BuildCtrlString(SP_START_SESSION, 0, nullptr, 0); + if (status < 0) { + goto Finish; + } + if ((hSession->fdChildWorkTCP = Base::DuplicateUvSocket(&hSession->hWorkTCP)) < 0) { + goto Finish; + } + uv_read_stop((uv_stream_t *)&hSession->hWorkTCP); + Base::SetTcpOptions((uv_tcp_t *)&hSession->hWorkTCP); + WRITE_LOG(LOG_DEBUG, "HdcHostTCP::Connect"); + Base::StartWorkThread(&ptrConnect->loopMain, ptrConnect->SessionWorkThread, Base::FinishWorkThread, hSession); + // wait for thread up + while (hSession->childLoop.active_handles == 0) { + uv_sleep(MINOR_TIMEOUT); + } + Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); + return; +Finish: + WRITE_LOG(LOG_FATAL, "Connect failed"); + ptrConnect->FreeSession(hSession->sessionId); +} + +HSession HdcHostTCP::ConnectDaemon(const string &connectKey) +{ + char ip[BUF_SIZE_TINY] = ""; + uint16_t port = 0; + if (Base::ConnectKey2IPPort(connectKey.c_str(), ip, &port) < 0) { + return nullptr; + } + + HdcSessionBase *ptrConnect = (HdcSessionBase *)clsMainBase; + HSession hSession = ptrConnect->MallocSession(true, CONN_TCP, this); + if (!hSession) { + return nullptr; + } + hSession->connectKey = connectKey; + struct sockaddr_in dest; + uv_ip4_addr(ip, port, &dest); + uv_connect_t *conn = new uv_connect_t(); + conn->data = hSession; + uv_tcp_connect(conn, (uv_tcp_t *)&hSession->hWorkTCP, (const struct sockaddr *)&dest, Connect); + return hSession; +} + +void HdcHostTCP::FindLanDaemon() +{ + uv_interface_address_t *info; + int count, i; + char ipAddr[BUF_SIZE_TINY] = ""; + if (broadcastFindWorking) { + return; + } + lstDaemonResult.clear(); + uv_interface_addresses(&info, &count); + i = count; + while (--i) { + uv_interface_address_t interface = info[i]; + if (interface.address.address4.sin_family == AF_INET6) { + continue; + } + uv_ip4_name(&interface.address.address4, ipAddr, sizeof(ipAddr)); + BroadcatFindDaemon(ipAddr); + } + uv_free_interface_addresses(info, count); +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/host/host_tcp.h b/services/flashd/host/host_tcp.h new file mode 100755 index 00000000..b5b85ab6 --- /dev/null +++ b/services/flashd/host/host_tcp.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_HOST_TCP_H +#define HDC_HOST_TCP_H +#include "host_common.h" + +namespace Hdc { +class HdcHostTCP : public HdcTCPBase { +public: + HdcHostTCP(const bool serverOrDaemonIn, void *ptrMainBase); + virtual ~HdcHostTCP(); + void FindLanDaemon(); + HSession ConnectDaemon(const string &connectKey); + void Stop(); + list lstDaemonResult; + +private: + static void BroadcastTimer(uv_idle_t *handle); + static void Connect(uv_connect_t *connection, int status); + void BroadcatFindDaemon(const char *broadcastLanIP); + void RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf); + + bool broadcastFindWorking; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/host/host_unity.cpp b/services/flashd/host/host_unity.cpp new file mode 100755 index 00000000..276682eb --- /dev/null +++ b/services/flashd/host/host_unity.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "host_unity.h" + +namespace Hdc { +HdcHostUnity::HdcHostUnity(HTaskInfo hTaskInfo) + : HdcTaskBase(hTaskInfo) +{ + Base::ZeroStruct(opContext); + opContext.thisClass = this; +} + +HdcHostUnity::~HdcHostUnity() +{ + WRITE_LOG(LOG_DEBUG, "HdcHostUnity::~HdcHostUnity finish"); +} + +bool HdcHostUnity::ReadyForRelease() +{ + if (!HdcTaskBase::ReadyForRelease()) { + return false; + } + if (opContext.enableLog && !opContext.hasFilelogClosed) { + return false; + } + return true; +} + +void HdcHostUnity::StopTask() +{ + // Do not detect RunningProtect, force to close + if (opContext.hasFilelogClosed) { + return; + } + if (opContext.enableLog) { + ++refCount; + opContext.fsClose.data = &opContext; + uv_fs_close(loopTask, &opContext.fsClose, opContext.fileLog, OnFileClose); + } +}; + +void HdcHostUnity::OnFileClose(uv_fs_t *req) +{ + uv_fs_req_cleanup(req); + ContextUnity *context = (ContextUnity *)req->data; + HdcHostUnity *thisClass = (HdcHostUnity *)context->thisClass; + context->hasFilelogClosed = true; + --thisClass->refCount; + return; +} + +bool HdcHostUnity::InitLocalLog(const char *path) +{ + uv_fs_t reqFs; + // block open + if (uv_fs_open(nullptr, &reqFs, path, UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, nullptr) + < 0) + return false; + uv_fs_req_cleanup(&reqFs); + opContext.fileLog = reqFs.result; + return true; +} + +void HdcHostUnity::OnFileIO(uv_fs_t *req) +{ + CtxUnityIO *contextIO = (CtxUnityIO *)req->data; + ContextUnity *context = (ContextUnity *)contextIO->context; + HdcHostUnity *thisClass = (HdcHostUnity *)context->thisClass; + uint8_t *bufIO = contextIO->bufIO; + uv_fs_req_cleanup(req); + --thisClass->refCount; + while (true) { + if (req->result <= 0) { + if (req->result < 0) { + WRITE_LOG(LOG_DEBUG, "Error OnFileIO: %s", uv_strerror((int)req->result)); + } + break; + } + context->fileIOIndex += req->result; + break; + } + delete[] bufIO; + delete contextIO; // req is part of contextIO, no need to release +} + +bool HdcHostUnity::AppendLocalLog(const char *bufLog, const int sizeLog) +{ + auto buf = new uint8_t[sizeLog]; + auto contextIO = new CtxUnityIO(); + if (!buf || !contextIO) { + if (buf) { + delete[] buf; + } + if (contextIO) { + delete contextIO; + } + return false; + } + uv_fs_t *req = &contextIO->fs; + contextIO->bufIO = buf; + contextIO->context = &opContext; + req->data = contextIO; + ++refCount; + + if (memcpy_s(buf, sizeLog, bufLog, sizeLog)) { + } + uv_buf_t iov = uv_buf_init((char *)buf, sizeLog); + uv_fs_write(loopTask, req, opContext.fileLog, &iov, 1, opContext.fileBufIndex, OnFileIO); + opContext.fileBufIndex += sizeLog; + return true; +} + +bool HdcHostUnity::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) +{ + bool ret = true; + // Both are executed, do not need to detect ChildReady + switch (command) { + case CMD_UNITY_BUGREPORT_INIT: { + if (strlen((char *)payload)) { // enable local log + if (!InitLocalLog((const char *)payload)) { + LogMsg(MSG_FAIL, "Cannot set locallog"); + ret = false; + break; + }; + opContext.enableLog = true; + } + SendToAnother(CMD_UNITY_BUGREPORT_INIT, nullptr, 0); + break; + } + case CMD_UNITY_BUGREPORT_DATA: { + if (opContext.enableLog) { + AppendLocalLog((const char *)payload, payloadSize); + } else { + ServerCommand(CMD_KERNEL_ECHO_RAW, payload, payloadSize); + } + break; + } + default: + break; + } + return ret; +}; +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/host/host_unity.h b/services/flashd/host/host_unity.h new file mode 100755 index 00000000..e4cb08f8 --- /dev/null +++ b/services/flashd/host/host_unity.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_HOST_UNITY_H +#define HDC_HOST_UNITY_H +#include "host_common.h" + +namespace Hdc { +class HdcHostUnity : public HdcTaskBase { +public: + HdcHostUnity(HTaskInfo hTaskInfo); + virtual ~HdcHostUnity(); + bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); + void StopTask(); + bool ReadyForRelease(); + +private: + struct ContextUnity { + bool enableLog; + uv_file fileLog; + uint64_t fileIOIndex; + uint64_t fileBufIndex; + bool hasFilelogClosed; + uv_fs_t fsClose; + HdcHostUnity *thisClass; + }; + struct CtxUnityIO { + uv_fs_t fs; + uint8_t *bufIO; + ContextUnity *context; + }; + static void OnFileIO(uv_fs_t *req); + static void OnFileClose(uv_fs_t *req); + bool InitLocalLog(const char *path); + bool AppendLocalLog(const char *bufLog, const int sizeLog); + + ContextUnity opContext; +}; +} // namespace Hdc +#endif // HDC_HOST_UNITY_H \ No newline at end of file diff --git a/services/flashd/host/host_updater.cpp b/services/flashd/host/host_updater.cpp index 00beb0f8..1092abc0 100755 --- a/services/flashd/host/host_updater.cpp +++ b/services/flashd/host/host_updater.cpp @@ -254,28 +254,10 @@ bool HostUpdater::CheckUpdateContinue(const uint16_t command, const uint8_t *pay return true; } -std::string HostUpdater::GetFlashdHelp() -{ - string help = "\n---------------------------------flash commands:-------------------------------------\n" - "flash commands:\n" - " target boot [-flashd] - Reboot the device or boot into flashd\n" - " update packagename - Update system by package\n" - " flash [-f] partition imagename - Flash partition by image\n" - " erase [-f] partition - Erase partition\n" - " format [-f] partition -t fs_type - Format partition -t [ext4 | f2fs]\n"; - return help; -} - bool HostUpdater::CheckMatchUpdate(const std::string &input, std::string &stringError, uint16_t &cmdFlag, bool &bJumpDo) { WRITE_LOG(LOG_DEBUG, "CheckMatchUpdate command:%s", input.c_str()); - if (!strcmp(input.c_str(), helpCmd.c_str())) { - cmdFlag = CMD_KERNEL_HELP; - stringError = HostUpdater::GetFlashdHelp(); - bJumpDo = true; - return true; - } size_t cmdLen = updateCmd.size(); if (!strncmp(input.c_str(), updateCmd.c_str(), updateCmd.size())) { cmdFlag = CMD_UPDATER_UPDATE_INIT; @@ -365,4 +347,4 @@ bool HostUpdater::ConfirmCommand(const string &commandIn, bool &closeInput) } return true; } -} // namespace Hdc +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/host/host_updater.h b/services/flashd/host/host_updater.h index 2e627782..174dfd4f 100755 --- a/services/flashd/host/host_updater.h +++ b/services/flashd/host/host_updater.h @@ -30,7 +30,6 @@ public: virtual ~HostUpdater(); bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) override; - static std::string GetFlashdHelp(); static bool CheckMatchUpdate(const std::string &input, std::string &stringError, uint16_t &cmdFlag, bool &bJumpDo); static bool ConfirmCommand(const string &commandIn, bool &closeInput); #ifdef UPDATER_UT diff --git a/services/flashd/host/host_usb.cpp b/services/flashd/host/host_usb.cpp new file mode 100755 index 00000000..2b9a9f6d --- /dev/null +++ b/services/flashd/host/host_usb.cpp @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "host_usb.h" +#include "server.h" + +namespace Hdc { +HdcHostUSB::HdcHostUSB(const bool serverOrDaemonIn, void *ptrMainBase, void *ctxUSBin) + : HdcUSBBase(serverOrDaemonIn, ptrMainBase) +{ + modRunning = false; + if (!ctxUSBin) { + return; + } + HdcServer *pServer = (HdcServer *)ptrMainBase; + uv_idle_init(&pServer->loopMain, &usbWork); + ctxUSB = (libusb_context *)ctxUSBin; + uv_timer_init(&pServer->loopMain, &devListWatcher); +} + +HdcHostUSB::~HdcHostUSB() +{ + if (modRunning) { + Stop(); + } + WRITE_LOG(LOG_DEBUG, "~HdcHostUSB"); +} + +void HdcHostUSB::Stop() +{ + if (!ctxUSB) { + return; + } + Base::TryCloseHandle((uv_handle_t *)&usbWork); + Base::TryCloseHandle((uv_handle_t *)&devListWatcher); + modRunning = false; +} + +int HdcHostUSB::Initial() +{ + if (!ctxUSB) { + WRITE_LOG(LOG_FATAL, "USB mod ctxUSB is nullptr, recompile please"); + return -1; + } + WRITE_LOG(LOG_DEBUG, "HdcHostUSB init"); + modRunning = true; + StartupUSBWork(); // Main thread registration, IO in sub-thread + return 0; +} + +// windows/mac's control port reset seems invalid? So we try to use soft interrupt +// if all platform 'libusb_reset_device()' work ok, commit this function and use it replace +// main thread call +void HdcHostUSB::SendUsbSoftReset(HUSB hUSB, uint32_t sessionId) +{ + struct ResetCtx { + USBHead usbPayloadHeader; + HUSB hUSB; + }; + ResetCtx *ctxReset = new ResetCtx(); + ctxReset->hUSB = hUSB; + + USBHead &usbPayloadHeader = ctxReset->usbPayloadHeader; + usbPayloadHeader.option = USB_OPTION_RESET; + usbPayloadHeader.sessionId = sessionId; + if (memcpy_s(usbPayloadHeader.flag, sizeof(usbPayloadHeader.flag), PACKET_FLAG.c_str(), + sizeof(usbPayloadHeader.flag)) + != EOK) { + delete ctxReset; + return; + } + auto resetUsbCallback = [](struct libusb_transfer *transfer) -> void LIBUSB_CALL { + ResetCtx *ctxReset = (ResetCtx *)transfer->user_data; + if (LIBUSB_TRANSFER_COMPLETED != transfer->status) { + WRITE_LOG(LOG_FATAL, "SendUSBRaw status:%d", transfer->status); + } + ctxReset->hUSB->sendIOComplete = true; + delete ctxReset; + libusb_free_transfer(transfer); + // has send soft reset, next reset daemon's send + WRITE_LOG(LOG_DEBUG, "Device reset singal send"); + }; + hUSB->lockDeviceHandle.lock(); + libusb_transfer *transferUsb = libusb_alloc_transfer(0); + libusb_fill_bulk_transfer(transferUsb, hUSB->devHandle, hUSB->epHost, (uint8_t *)&usbPayloadHeader, sizeof(USBHead), + resetUsbCallback, ctxReset, GLOBAL_TIMEOUT * TIME_BASE); + int err = libusb_submit_transfer(transferUsb); + if (err < 0) { + WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", err); + delete ctxReset; + } else { + hUSB->sendIOComplete = false; + } + hUSB->lockDeviceHandle.unlock(); +} + +bool HdcHostUSB::DetectMyNeed(libusb_device *device, string &sn) +{ + bool ret = false; + HUSB hUSB = new HdcUSB(); + hUSB->device = device; + // just get usb SN, close handle immediately + int childRet = OpenDeviceMyNeed(hUSB); + if (childRet < 0) { + delete hUSB; + return false; + } + libusb_release_interface(hUSB->devHandle, hUSB->interfaceNumber); + libusb_close(hUSB->devHandle); + hUSB->devHandle = nullptr; + + WRITE_LOG(LOG_INFO, "Needed device found, busid:%d devid:%d connectkey:%s", hUSB->busId, hUSB->devId, + hUSB->serialNumber.c_str()); + // USB device is automatically connected after recognition, auto connect USB + UpdateUSBDaemonInfo(hUSB, nullptr, STATUS_READY); + HdcServer *hdcServer = (HdcServer *)clsMainBase; + HSession hSession = hdcServer->MallocSession(true, CONN_USB, this); + hSession->connectKey = hUSB->serialNumber; + uv_timer_t *waitTimeDoCmd = new uv_timer_t; + uv_timer_init(&hdcServer->loopMain, waitTimeDoCmd); + waitTimeDoCmd->data = hSession; + constexpr uint16_t PRECONNECT_INTERVAL = 3000; + uv_timer_start(waitTimeDoCmd, hdcServer->UsbPreConnect, 0, PRECONNECT_INTERVAL); + mapIgnoreDevice[sn] = HOST_USB_REGISTER; + ret = true; + delete hUSB; + return ret; +} + +// sub-thread all called +void HdcHostUSB::PenddingUSBIO(uv_idle_t *handle) +{ + libusb_context *ctxUSB = (libusb_context *)handle->data; + // every plug,handle,libusb_handle_events + struct timeval zerotime; + int nComplete = 0; + zerotime.tv_sec = 0; + zerotime.tv_usec = 1; // if == 0,windows will be high CPU load + libusb_handle_events_timeout_completed(ctxUSB, &zerotime, &nComplete); +} + +void HdcHostUSB::KickoutZombie(HSession hSession) +{ + HdcServer *ptrConnect = (HdcServer *)hSession->classInstance; + HUSB hUSB = hSession->hUSB; + if (!hUSB->devHandle || hSession->isDead) { + return; + } + if (LIBUSB_ERROR_NO_DEVICE != libusb_kernel_driver_active(hUSB->devHandle, hUSB->interfaceNumber)) { + return; + } + ptrConnect->FreeSession(hSession->sessionId); +} + +void HdcHostUSB::RemoveIgnoreDevice(string &mountInfo) +{ + if (mapIgnoreDevice.count(mountInfo)) { + mapIgnoreDevice.erase(mountInfo); + } +} + +void HdcHostUSB::ReviewUsbNodeLater(string &nodeKey) +{ + HdcServer *hdcServer = (HdcServer *)clsMainBase; + // add to ignore list + mapIgnoreDevice[nodeKey] = HOST_USB_IGNORE; + int delayRemoveFromList = intervalDevCheck * MINOR_TIMEOUT; // wait little time for daemon reinit + Base::DelayDo(&hdcServer->loopMain, delayRemoveFromList, 0, nodeKey, nullptr, + [this](const uint8_t flag, string &msg, const void *) -> void { RemoveIgnoreDevice(msg); }); +} + +void HdcHostUSB::WatchDevPlugin(uv_timer_t *handle) +{ + HdcHostUSB *thisClass = (HdcHostUSB *)handle->data; + HdcServer *ptrConnect = (HdcServer *)thisClass->clsMainBase; + libusb_device **devs = nullptr; + libusb_device *dev = nullptr; + // kick zombie + ptrConnect->EnumUSBDeviceRegister(KickoutZombie); + // find new + ssize_t cnt = libusb_get_device_list(thisClass->ctxUSB, &devs); + if (cnt < 0) { + WRITE_LOG(LOG_FATAL, "Failed to get device list"); + return; + } + int i = 0; + // linux replug devid increment,windows will be not + while ((dev = devs[i++]) != nullptr) { // must postfix++ + string szTmpKey = Base::StringFormat("%d-%d", libusb_get_bus_number(dev), libusb_get_device_address(dev)); + // check is in ignore list + UsbCheckStatus statusCheck = thisClass->mapIgnoreDevice[szTmpKey]; + if (statusCheck == HOST_USB_IGNORE || statusCheck == HOST_USB_REGISTER) { + continue; + } + string sn = szTmpKey; + if (!thisClass->DetectMyNeed(dev, sn)) { + thisClass->ReviewUsbNodeLater(szTmpKey); + } + } + libusb_free_device_list(devs, 1); +} + +int HdcHostUSB::StartupUSBWork() +{ + // Because libusb(winusb backend) does not support hotplug under win32, we use list mode for all platforms + WRITE_LOG(LOG_DEBUG, "USBHost loopfind mode"); + devListWatcher.data = this; + uv_timer_start(&devListWatcher, WatchDevPlugin, 0, intervalDevCheck); + // Running pendding in independent threads does not significantly improve the efficiency + usbWork.data = ctxUSB; + uv_idle_start(&usbWork, PenddingUSBIO); + return 0; +} + +int HdcHostUSB::CheckDescriptor(HUSB hUSB) +{ + char serialNum[BUF_SIZE_MEDIUM] = ""; + int childRet = 0; + struct libusb_device_descriptor desc; + int curBus = libusb_get_bus_number(hUSB->device); + int curDev = libusb_get_device_address(hUSB->device); + hUSB->busId = curBus; + hUSB->devId = curDev; + if (libusb_get_device_descriptor(hUSB->device, &desc)) { + WRITE_LOG(LOG_DEBUG, "CheckDescriptor libusb_get_device_descriptor failed"); + return -1; + } + // Get the serial number of the device, if there is no serial number, use the ID number to replace + // If the device is not in time, occasionally can't get it, this is determined by the external factor, cannot be + // changed. LIBUSB_SUCCESS + childRet = libusb_get_string_descriptor_ascii(hUSB->devHandle, desc.iSerialNumber, (uint8_t *)serialNum, + sizeof(serialNum)); + if (childRet < 0) { + hUSB->serialNumber = Base::StringFormat("%d-%d", curBus, curDev); + } else { + hUSB->serialNumber = serialNum; + } + return 0; +} + +// hSession can be null +void HdcHostUSB::UpdateUSBDaemonInfo(HUSB hUSB, HSession hSession, uint8_t connStatus) +{ + // add to list + HdcServer *pServer = (HdcServer *)clsMainBase; + HdcDaemonInformation di; + di.connectKey = hUSB->serialNumber; + di.connType = CONN_USB; + di.connStatus = connStatus; + di.hSession = hSession; + di.usbMountPoint = ""; + di.usbMountPoint = Base::StringFormat("%d-%d", hUSB->busId, hUSB->devId); + + HDaemonInfo pDi = nullptr; + HDaemonInfo hdiNew = &di; + pServer->AdminDaemonMap(OP_QUERY, hUSB->serialNumber, pDi); + if (!pDi) { + pServer->AdminDaemonMap(OP_ADD, hUSB->serialNumber, hdiNew); + } else { + pServer->AdminDaemonMap(OP_UPDATE, hUSB->serialNumber, hdiNew); + } +} + +bool HdcHostUSB::IsDebuggableDev(const struct libusb_interface_descriptor *ifDescriptor) +{ + constexpr uint8_t harmonyEpNum = 2; + constexpr uint8_t harmonyClass = 0xff; + constexpr uint8_t harmonySubClass = 0x50; + constexpr uint8_t harmonyProtocol = 0x01; + + if (ifDescriptor->bInterfaceClass != harmonyClass || ifDescriptor->bInterfaceSubClass != harmonySubClass + || ifDescriptor->bInterfaceProtocol != harmonyProtocol) { + return false; + } + if (ifDescriptor->bNumEndpoints != harmonyEpNum) { + return false; + } + return true; +} + +int HdcHostUSB::CheckActiveConfig(libusb_device *device, HUSB hUSB) +{ + unsigned int j = 0; + int ret = -1; + struct libusb_config_descriptor *descConfig = nullptr; + if (libusb_get_active_config_descriptor(device, &descConfig)) { + return -1; + } + for (j = 0; j < descConfig->bNumInterfaces; ++j) { + const struct libusb_interface *interface = &descConfig->interface[j]; + if (interface->num_altsetting >= 1) { + const struct libusb_interface_descriptor *ifDescriptor = &interface->altsetting[0]; + if (!IsDebuggableDev(ifDescriptor)) { + continue; + } + hUSB->interfaceNumber = ifDescriptor->bInterfaceNumber; + unsigned int k = 0; + for (k = 0; k < ifDescriptor->bNumEndpoints; ++k) { + const struct libusb_endpoint_descriptor *ep_desc = &ifDescriptor->endpoint[k]; + if ((ep_desc->bmAttributes & 0x03) == LIBUSB_TRANSFER_TYPE_BULK) { + if (ep_desc->bEndpointAddress & LIBUSB_ENDPOINT_IN) { + hUSB->epDevice = ep_desc->bEndpointAddress; + } else { + hUSB->epHost = ep_desc->bEndpointAddress; + } + hUSB->wMaxPacketSize = ep_desc->wMaxPacketSize; + } + } + if (hUSB->epDevice == 0 || hUSB->epHost == 0) { + break; + } + ret = 0; + } + } + libusb_free_config_descriptor(descConfig); + return ret; +} + +void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfer) +{ + HSession hSession = (HSession)transfer->user_data; + HdcHostUSB *thisClass = (HdcHostUSB *)hSession->classModule; + HUSB hUSB = hSession->hUSB; + bool bOK = false; + int childRet = 0; + constexpr int infinity = 0; // ignore timeout + while (true) { + if (!thisClass->modRunning || (hSession->isDead && 0 == hSession->sendRef)) + break; + if (LIBUSB_TRANSFER_COMPLETED != transfer->status) { + WRITE_LOG(LOG_FATAL, "Host usb not LIBUSB_TRANSFER_COMPLETED, status:%d", transfer->status); + break; + } + childRet + = thisClass->SendToHdcStream(hSession, reinterpret_cast(&hSession->dataPipe[STREAM_MAIN]), + hUSB->bufDevice, transfer->actual_length); + if (childRet != RET_SUCCESS && childRet != ERR_SESSION_NOFOUND) { + break; + } + hUSB->lockDeviceHandle.lock(); + // loop self + libusb_fill_bulk_transfer(transfer, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, hUSB->sizeEpBuf, + ReadUSBBulkCallback, hSession, infinity); + childRet = libusb_submit_transfer(transfer); + hUSB->lockDeviceHandle.unlock(); + if (childRet < 0) { + WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", childRet); + break; + } + bOK = true; + break; + } + if (!bOK) { + auto server = reinterpret_cast(thisClass->clsMainBase); + server->FreeSession(hSession->sessionId); + hUSB->recvIOComplete = true; + WRITE_LOG(LOG_WARN, "ReadUSBBulkCallback failed"); + } +} + +void HdcHostUSB::RegisterReadCallback(HSession hSession) +{ + HUSB hUSB = hSession->hUSB; + if (hSession->isDead || !modRunning) { + return; + } + hSession->hUSB->transferRecv->user_data = hSession; + hUSB->lockDeviceHandle.lock(); + // first bulk-read must be Okay and no timeout, otherwise failed. + libusb_fill_bulk_transfer(hSession->hUSB->transferRecv, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, + hUSB->sizeEpBuf, ReadUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); + int childRet = libusb_submit_transfer(hSession->hUSB->transferRecv); + hUSB->lockDeviceHandle.unlock(); + if (childRet == 0) { + hSession->hUSB->recvIOComplete = false; + } +} + +// ==0 Represents new equipment and is what we need,<0 my need +int HdcHostUSB::OpenDeviceMyNeed(HUSB hUSB) +{ + libusb_device *device = hUSB->device; + int ret = -1; + if (LIBUSB_SUCCESS != libusb_open(device, &hUSB->devHandle)) { + return -100; + } + while (modRunning) { + libusb_device_handle *handle = hUSB->devHandle; + if (CheckDescriptor(hUSB)) { + break; + } + if (CheckActiveConfig(device, hUSB)) { + break; + } + // USB filter rules are set according to specific device + // pedding device + libusb_claim_interface(handle, hUSB->interfaceNumber); + ret = 0; + break; + } + if (ret) { + // not my need device + libusb_close(hUSB->devHandle); + hUSB->devHandle = nullptr; + } + return ret; +} + +// at main thread +void LIBUSB_CALL HdcHostUSB::WriteUSBBulkCallback(struct libusb_transfer *transfer) +{ + USBHead *usbHead = reinterpret_cast(transfer->buffer); + HSession hSession = reinterpret_cast(transfer->user_data); + HdcSessionBase *server = reinterpret_cast(hSession->classInstance); + if (usbHead->option & USB_OPTION_TAIL) { + --hSession->sendRef; + } + if (LIBUSB_TRANSFER_COMPLETED != transfer->status || (hSession->isDead && 0 == hSession->sendRef)) { + WRITE_LOG(LOG_FATAL, "SendUSBRaw status:%d", transfer->status); + if (hSession->hUSB->transferRecv != nullptr) { + libusb_cancel_transfer(hSession->hUSB->transferRecv); + } + server->FreeSession(hSession->sessionId); + } + hSession->hUSB->sendIOComplete = true; + hSession->hUSB->cvTransferSend.notify_one(); +} + +// libusb can send directly across threads?!!! +// Just call from child work thread, it will be block when overlap full +int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) +{ + int ret = ERR_GENERIC; + int childRet = -1; + HUSB hUSB = hSession->hUSB; + while (true) { + if (memcpy_s(hUSB->bufHost, length, data, length) != EOK) { + ret = ERR_BUF_COPY; + break; + } + hUSB->lockDeviceHandle.lock(); + std::unique_lock lock(hUSB->lockSend); + hUSB->sendIOComplete = false; + libusb_fill_bulk_transfer(hUSB->transferSend, hUSB->devHandle, hUSB->epHost, hUSB->bufHost, length, + WriteUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); + childRet = libusb_submit_transfer(hUSB->transferSend); + hUSB->lockDeviceHandle.unlock(); + if (childRet < 0) { + ret = ERR_IO_FAIL; + break; + } + ret = length; + hUSB->cvTransferSend.wait(lock, [hUSB]() { return hUSB->sendIOComplete; }); + break; + } + if (ret < 0) { + --hSession->sendRef; + if (hUSB->transferRecv != nullptr) { + libusb_cancel_transfer(hUSB->transferRecv); + } + } + return ret; +} + +bool HdcHostUSB::FindDeviceByID(HUSB hUSB, const char *usbMountPoint, libusb_context *ctxUSB) +{ + libusb_device **listDevices = nullptr; + bool ret = false; + char tmpStr[BUF_SIZE_TINY] = ""; + int busNum = 0; + int devNum = 0; + int curBus = 0; + int curDev = 0; + + int device_num = libusb_get_device_list(ctxUSB, &listDevices); + if (device_num <= 0) { + libusb_free_device_list(listDevices, 1); + return false; + } + if (strchr(usbMountPoint, '-') && EOK == strcpy_s(tmpStr, sizeof(tmpStr), usbMountPoint)) { + *strchr(tmpStr, '-') = '\0'; + busNum = atoi(tmpStr); + devNum = atoi(tmpStr + strlen(tmpStr) + 1); + } else + return false; + + int i = 0; + for (i = 0; i < device_num; ++i) { + struct libusb_device_descriptor desc; + if (LIBUSB_SUCCESS != libusb_get_device_descriptor(listDevices[i], &desc)) { + break; + } + curBus = libusb_get_bus_number(listDevices[i]); + curDev = libusb_get_device_address(listDevices[i]); + if ((curBus == busNum && curDev == devNum)) { + hUSB->device = listDevices[i]; + int childRet = OpenDeviceMyNeed(hUSB); + if (!childRet) { + ret = true; + } + break; + } + } + libusb_free_device_list(listDevices, 1); + return ret; +} + +bool HdcHostUSB::ReadyForWorkThread(HSession hSession) +{ + HdcUSBBase::ReadyForWorkThread(hSession); + return true; +}; + +// Determines that daemonInfo must have the device +HSession HdcHostUSB::ConnectDetectDaemon(const HSession hSession, const HDaemonInfo pdi) +{ + HdcServer *pServer = (HdcServer *)clsMainBase; + HUSB hUSB = hSession->hUSB; + hUSB->usbMountPoint = pdi->usbMountPoint; + hUSB->ctxUSB = ctxUSB; + if (!FindDeviceByID(hUSB, hUSB->usbMountPoint.c_str(), hUSB->ctxUSB)) { + pServer->FreeSession(hSession->sessionId); + return nullptr; + } + UpdateUSBDaemonInfo(hUSB, hSession, STATUS_CONNECTED); + RegisterReadCallback(hSession); + hUSB->usbMountPoint = pdi->usbMountPoint; + WRITE_LOG(LOG_DEBUG, "HSession HdcHostUSB::ConnectDaemon"); + + Base::StartWorkThread(&pServer->loopMain, pServer->SessionWorkThread, Base::FinishWorkThread, hSession); + // wait for thread up + while (hSession->childLoop.active_handles == 0) { + uv_sleep(1); + } + auto ctrl = pServer->BuildCtrlString(SP_START_SESSION, 0, nullptr, 0); + Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); + return hSession; +} +} // namespace Hdc diff --git a/services/flashd/host/host_usb.h b/services/flashd/host/host_usb.h new file mode 100755 index 00000000..edafd789 --- /dev/null +++ b/services/flashd/host/host_usb.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_HOST_USB_H +#define HDC_HOST_USB_H +#include "host_common.h" + +namespace Hdc { +class HdcHostUSB : public HdcUSBBase { +public: + HdcHostUSB(const bool serverOrDaemonIn, void *ptrMainBase, void *ctxUSBin); + virtual ~HdcHostUSB(); + int Initial(); + int SendUSBRaw(HSession hSession, uint8_t *data, const int length); + HSession ConnectDetectDaemon(const HSession hSession, const HDaemonInfo pdi); + void Stop(); + void RemoveIgnoreDevice(string &mountInfo); + +private: + enum UsbCheckStatus { + HOST_USB_IGNORE = 1, + HOST_USB_READY, + HOST_USB_REGISTER, + }; + static int LIBUSB_CALL HotplugHostUSBCallback(libusb_context *ctx, libusb_device *device, + libusb_hotplug_event event, void *userData); + static void PenddingUSBIO(uv_idle_t *handle); + static void WatchDevPlugin(uv_timer_t *handle); + static void KickoutZombie(HSession hSession); + static void LIBUSB_CALL WriteUSBBulkCallback(struct libusb_transfer *transfer); + static void LIBUSB_CALL ReadUSBBulkCallback(struct libusb_transfer *transfer); + int StartupUSBWork(); + int CheckActiveConfig(libusb_device *device, HUSB hUSB); + int OpenDeviceMyNeed(HUSB hUSB); + int CheckDescriptor(HUSB hUSB); + bool IsDebuggableDev(const struct libusb_interface_descriptor *ifDescriptor); + bool ReadyForWorkThread(HSession hSession); + bool FindDeviceByID(HUSB hUSB, const char *usbMountPoint, libusb_context *ctxUSB); + bool DetectMyNeed(libusb_device *device, string &sn); + void SendUsbSoftReset(HUSB hUSB, uint32_t sessionId); + void RestoreHdcProtocol(HUSB hUsb, const uint8_t *buf, int bufSize); + void UpdateUSBDaemonInfo(HUSB hUSB, HSession hSession, uint8_t connStatus); + void RegisterReadCallback(HSession hSession); + void ReviewUsbNodeLater(string &nodeKey); + + uv_idle_t usbWork; + libusb_context *ctxUSB; + uv_timer_t devListWatcher; + map mapIgnoreDevice; + const int intervalDevCheck = 3000; + +private: +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/host/main.cpp b/services/flashd/host/main.cpp new file mode 100755 index 00000000..016e3dc2 --- /dev/null +++ b/services/flashd/host/main.cpp @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "server.h" +#include "server_for_client.h" + +#ifndef HARMONY_PROJECT +#include "../test/ut_command.h" +using namespace HdcTest; +#endif + +#include "server.h" +#include "server_for_client.h" +using namespace Hdc; + +static bool g_isServerMode = false; +static bool g_isPullServer = true; +static bool g_isPcDebugRun = false; +static bool g_isTCPorUSB = false; +static auto g_logLevel = LOG_LEVEL_FULL; +static int g_isTestMethod = 0; +static string g_connectKey = ""; +static string g_serverListenString = DEFAULT_SERVER_ADDR; + +namespace Hdc { +// return value: 0 == not command, 1 == one command, 2 == double command +int IsRegisterCommand(string &outCommand, const char *cmd, const char *cmdnext) +{ + string sCmdNext = cmdnext == nullptr ? string("") : string(cmdnext); + string doubleCommand = cmd + string(" ") + sCmdNext; + vector registerCommand; + registerCommand.push_back(CMDSTR_SOFTWARE_VERSION); + registerCommand.push_back(CMDSTR_SOFTWARE_HELP); + registerCommand.push_back(CMDSTR_TARGET_DISCOVER); + registerCommand.push_back(CMDSTR_LIST_TARGETS); + registerCommand.push_back(CMDSTR_CONNECT_ANY); + registerCommand.push_back(CMDSTR_CONNECT_TARGET); + registerCommand.push_back(CMDSTR_TARGET_REBOOT); + registerCommand.push_back(CMDSTR_SERVICE_KILL); + registerCommand.push_back(CMDSTR_SERVICE_START); + registerCommand.push_back(CMDSTR_TARGET_MODE); + + // flashd + registerCommand.push_back(CMDSTR_UPDATE_SYSTEM); + registerCommand.push_back(CMDSTR_FLASH_PARTITION); + registerCommand.push_back(CMDSTR_ERASE_PARTITION); + registerCommand.push_back(CMDSTR_FORMAT_PARTITION); + for (string v : registerCommand) { + if (doubleCommand == v) { + outCommand = doubleCommand; + return 2; + } + if (cmd == v) { + outCommand = cmd; + return 1; + } + } + return 0; +} + +void AppendCwdWhenTransfer(string &outCommand) +{ + if (outCommand != CMDSTR_FILE_SEND && outCommand != CMDSTR_FILE_RECV && outCommand != CMDSTR_APP_INSTALL + && outCommand != CMDSTR_APP_SIDELOAD) { + return; + } + char path[PATH_MAX] = ""; + size_t size = sizeof(path); + if (uv_cwd(path, &size) < 0) + return; + if (path[strlen(path) - 1] != Base::GetPathSep()) { + path[strlen(path)] = Base::GetPathSep(); + } + outCommand += outCommand.size() ? " -cwd " : "-cwd "; + outCommand += path; +} + +int SplitOptionAndCommand(int argc, const char **argv, string &outOption, string &outCommand) +{ + bool foundCommand = false; + int resultChild = 0; + // we want to start from 1, ignore argv[0], but it has issue + for (int i = 0; i < argc; ++i) { + if (!foundCommand) { + resultChild = IsRegisterCommand(outCommand, argv[i], (i == argc - 1) ? nullptr : argv[i + 1]); + if (resultChild > 0) { + foundCommand = true; + if (resultChild == 2) { + ++i; + } + AppendCwdWhenTransfer(outCommand); + continue; + } + } + if (foundCommand) { + outCommand += outCommand.size() ? " " : ""; + string rawCmd = argv[i]; + string packageCmd = Base::StringFormat("\"%s\"", argv[i]); + outCommand += rawCmd.find(" ") == string::npos ? rawCmd : packageCmd; + } else { + outOption += outOption.size() ? " " : ""; + outOption += argv[i]; + } + } + return 0; +} + +int RunServerMode(string &serverListenString) +{ + HdcServer server(true); + if (!server.Initial(serverListenString.c_str())) { + Base::PrintMessage("Initial failed"); + return -1; + } + server.WorkerPendding(); + return 0; +} + +int RunPcDebugMode(bool isPullServer, bool isTCPorUSB, int isTestMethod) +{ +#ifdef HARMONY_PROJECT + Base::PrintMessage("Not support command..."); +#else + pthread_t pt; + if (isPullServer) { + pthread_create(&pt, nullptr, TestBackgroundServerForClient, nullptr); + uv_sleep(200); // give time to start serverForClient,at least 200ms + } + TestRuntimeCommandSimple(isTCPorUSB, isTestMethod, true); + if (isPullServer) { + pthread_join(pt, nullptr); + WRITE_LOG(LOG_DEBUG, "!!!!!!!!!Server finish"); + } +#endif + return 0; +} + +int RunClientMode(string &commands, string &serverListenString, string &connectKey, bool isPullServer) +{ + uv_loop_t loopMain; + uv_loop_init(&loopMain); + HdcClient client(false, serverListenString, &loopMain); + if (!commands.size()) { + Base::PrintMessage("Unknow operation command..."); + TranslateCommand::Usage(); + return 0; + } + if (!strncmp(commands.c_str(), CMDSTR_SERVICE_START.c_str(), CMDSTR_SERVICE_START.size()) + || !strncmp(commands.c_str(), CMDSTR_SERVICE_KILL.c_str(), CMDSTR_SERVICE_KILL.size()) + || !strncmp(commands.c_str(), CMDSTR_GENERATE_KEY.c_str(), CMDSTR_GENERATE_KEY.size())) { + client.CtrlServiceWork(commands.c_str()); + return 0; + } + if (isPullServer && serverListenString == DEFAULT_SERVER_ADDR + && Base::ProgramMutex(SERVER_NAME.c_str(), true) == 0) { + // default pullup, just default listenstr.If want to customer listen-string, please use 'hdc -m -s lanip:port' + HdcServer::PullupServer(DEFAULT_SERVER_ADDR.c_str()); + uv_sleep(300); // give time to start serverForClient,at least 200ms + } + client.Initial(connectKey); + client.ExecuteCommand(commands.c_str()); + return 0; +} + +bool ParseServerListenString(string &serverListenString, char *optarg) +{ + if (strlen(optarg) > 24) { + Base::PrintMessage("Unknow content of parament '-s'"); + return false; + } + char buf[BUF_SIZE_TINY] = ""; + if (strcpy_s(buf, sizeof(buf), optarg) < 0) { + return false; + } + char *p = strchr(buf, ':'); + if (!p) { // Only port + if (strlen(buf) > 5) { + Base::PrintMessage("The port-string's length must < 5"); + return false; + } + int port = atoi(buf); + if (port <= 0 || port > MAX_IP_PORT) { + Base::PrintMessage("Port range incorrect"); + return false; + } + snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "127.0.0.1:%d", port); + serverListenString = buf; + } else { + *p = '\0'; + int port = atoi(p + 1); + sockaddr_in addr; + if ((port <= 0 || port > MAX_IP_PORT) || uv_ip4_addr(buf, port, &addr) < 0) { + Base::PrintMessage("-s content incorrect."); + return false; + } + serverListenString = optarg; + } + return true; +} + +bool GetCommandlineOptions(int optArgc, const char *optArgv[]) +{ + int ch = 0; + bool needExit = false; + opterr = 0; + // get option parameters first + while ((ch = getopt(optArgc, (char *const *)optArgv, "hvpfms:d:t:l:")) != -1) { + switch (ch) { + case 'h': { + string usage = Hdc::TranslateCommand::Usage(); + fprintf(stderr, "%s", usage.c_str()); + needExit = true; + return needExit; + } + case 'v': { + string ver = Base::GetVersion(); + fprintf(stdout, "%s\n", ver.c_str()); + needExit = true; + return needExit; + } + case 'f': { // [not-publish] + break; + } + case 'l': { + int logLevel = atoi(optarg); + if (logLevel < 0 || logLevel > LOG_LAST) { + Base::PrintMessage("Loglevel error!"); + needExit = true; + return needExit; + } + g_logLevel = logLevel; + Base::SetLogLevel(logLevel); + break; + } + case 'm': { // [not-publish] is server mode,or client mode + g_isServerMode = true; + break; + } + case 'p': { // [not-publish] not pullup server + g_isPullServer = false; + break; + } + case 't': { // key + if (strlen(optarg) > MAX_CONNECTKEY_SIZE) { + Base::PrintMessage("Sizeo of of parament '-t' %d is too long", strlen(optarg)); + needExit = true; + return needExit; + } + g_connectKey = optarg; + break; + } + case 's': { + if (!Hdc::ParseServerListenString(g_serverListenString, optarg)) { + needExit = true; + return needExit; + } + break; + } + case 'd': // [Undisclosed parameters] debug mode + g_isPcDebugRun = true; + if (optarg[0] == 't') { + g_isTCPorUSB = true; + } else if (optarg[0] == 'u') { + g_isTCPorUSB = false; + } else { + Base::PrintMessage("Unknown debug parameters"); + needExit = true; + return needExit; + } + g_isTestMethod = atoi(optarg + 1); + break; + case '?': + break; + default: { + Base::PrintMessage("Unknown parameters"); + needExit = true; + return needExit; + } + } + } + return needExit; +} +} + +#ifndef UNIT_TEST +// hdc -l4 -m -s ip:port|hdc -l4 -m +// hdc -l4 - s ip:port list targets +int main(int argc, const char *argv[]) +{ + string options; + string commands; + Hdc::SplitOptionAndCommand(argc, argv, options, commands); + int optArgc = 0; + char **optArgv = Base::SplitCommandToArgs(options.c_str(), &optArgc); + bool cmdOptionResult = GetCommandlineOptions(optArgc, (const char **)optArgv); + delete[]((char *)optArgv); + if (cmdOptionResult) { + return 0; + } + if (g_isServerMode) { + // -m server.Run alone in the background, no -s will be listen loopback address, + Base::SetLogLevel(g_logLevel); // default level LOG_LEVEL_FULL + Hdc::RunServerMode(g_serverListenString); + } else if (g_isPcDebugRun) { + Hdc::RunPcDebugMode(g_isPullServer, g_isTCPorUSB, g_isTestMethod); + } else { + Hdc::RunClientMode(commands, g_serverListenString, g_connectKey, g_isPullServer); + } + WRITE_LOG(LOG_DEBUG, "!!!!!!!!!Main finish main"); + return 0; +} +#endif // no UNIT_TEST diff --git a/services/flashd/host/server.cpp b/services/flashd/host/server.cpp new file mode 100755 index 00000000..90a4b994 --- /dev/null +++ b/services/flashd/host/server.cpp @@ -0,0 +1,795 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "server.h" + +namespace Hdc { +HdcServer::HdcServer(bool serverOrDaemonIn) + : HdcSessionBase(serverOrDaemonIn) +{ + clsTCPClt = nullptr; + clsUSBClt = nullptr; + clsServerForClient = nullptr; + uv_rwlock_init(&daemonAdmin); + uv_rwlock_init(&forwardAdmin); +} + +HdcServer::~HdcServer() +{ + WRITE_LOG(LOG_DEBUG, "~HdcServer"); + uv_rwlock_destroy(&daemonAdmin); + uv_rwlock_destroy(&forwardAdmin); +} + +void HdcServer::ClearInstanceResource() +{ + TryStopInstance(); + Base::TryCloseLoop(&loopMain, "HdcServer::~HdcServer"); + if (clsTCPClt) { + delete clsTCPClt; + } + if (clsUSBClt) { + delete clsUSBClt; + } + if (clsServerForClient) { + delete (static_cast(clsServerForClient)); + } +} + +void HdcServer::TryStopInstance() +{ + ClearSessions(); + if (clsTCPClt) { + clsTCPClt->Stop(); + } + if (clsUSBClt) { + clsUSBClt->Stop(); + } + if (clsServerForClient) { + ((HdcServerForClient *)clsServerForClient)->Stop(); + } + ReMainLoopForInstanceClear(); + ClearMapDaemonInfo(); +} + +bool HdcServer::Initial(const char *listenString) +{ + if (Base::ProgramMutex(SERVER_NAME.c_str(), false) != 0) { + WRITE_LOG(LOG_FATAL, "Other instance already running, program mutex failed"); + return false; + } + clsServerForClient = new HdcServerForClient(true, listenString, this, &loopMain); + clsTCPClt = new HdcHostTCP(true, this); + clsUSBClt = new HdcHostUSB(true, this, ctxUSB); + if (!clsServerForClient || !clsTCPClt || !clsUSBClt) { + WRITE_LOG(LOG_FATAL, "Class init failed"); + return false; + } + (static_cast(clsServerForClient))->Initial(); + clsUSBClt->Initial(); + return true; +} + +bool HdcServer::PullupServerWin32(const char *path, const char *listenString) +{ +#ifdef _WIN32 + char buf[BUF_SIZE_SMALL] = ""; + char shortPath[MAX_PATH] = ""; + int ret = GetShortPathName(path, shortPath, MAX_PATH); + std::string runPath = shortPath; + if (ret == 0) { + int err = GetLastError(); + WRITE_LOG(LOG_WARN, "GetShortPath path:[%s] err:%d errmsg:%s", path, err, strerror(err)); + string uvPath = path; + runPath = uvPath.substr(uvPath.find_last_of("/\\") + 1); + } + WRITE_LOG(LOG_DEBUG, "server shortpath:[%s] runPath:[%s]", shortPath, runPath.c_str()); + if (sprintf_s(buf, sizeof(buf), "%s -l4 -s %s -m", runPath.c_str(), listenString) < 0) { + return false; + } + WRITE_LOG(LOG_DEBUG, "Run server in debug-forground, cmd:%s", buf); + STARTUPINFO si; + Base::ZeroStruct(si); + si.cb = sizeof(STARTUPINFO); + PROCESS_INFORMATION pi; + Base::ZeroStruct(pi); +#ifndef HDC_DEBUG + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; +#endif + CreateProcess(nullptr, buf, nullptr, nullptr, true, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); +#endif + return true; +} + +// Only detects that the default call is in the loop address, the other tubes are not +bool HdcServer::PullupServer(const char *listenString) +{ + char path[BUF_SIZE_SMALL] = ""; + size_t nPathSize = sizeof(path); + int ret = uv_exepath(path, &nPathSize); + if (ret < 0) { + WRITE_LOG(LOG_WARN, "uvexepath ret:%d error:%s", ret, uv_err_name(ret)); + return false; + } + +#ifdef _WIN32 + if (!PullupServerWin32(path, listenString)) { + return false; + } +#else + pid_t pc = fork(); // create process as daemon process + if (pc < 0) { + return false; + } else if (!pc) { + int i; + const int maxFD = 1024; + for (i = 0; i < maxFD; ++i) { + // close file pipe + close(i); + } + execl(path, "hdc", "-m", "-s", listenString, nullptr); + exit(0); + return true; + } + // orig process +#endif + // wait little time, util backend-server work ready + uv_sleep(TIME_BASE); + return true; +} + +void HdcServer::ClearMapDaemonInfo() +{ + map::iterator iter; + uv_rwlock_rdlock(&daemonAdmin); + for (iter = mapDaemon.begin(); iter != mapDaemon.end();) { + string sKey = iter->first; + HDaemonInfo hDi = iter->second; + delete hDi; + ++iter; + } + uv_rwlock_rdunlock(&daemonAdmin); + uv_rwlock_wrlock(&daemonAdmin); + mapDaemon.clear(); + uv_rwlock_wrunlock(&daemonAdmin); +} + +void HdcServer::BuildDaemonVisableLine(HDaemonInfo hdi, bool fullDisplay, string &out) +{ + if (fullDisplay) { + string sConn; + string sStatus; + switch (hdi->connType) { + case CONN_TCP: + sConn = "TCP"; + break; + case CONN_USB: + sConn = "USB"; + break; + + case CONN_BT: + sConn = "BT"; + break; + default: + sConn = "UNKNOW"; + break; + } + switch (hdi->connStatus) { + case STATUS_READY: + sStatus = "Ready"; + break; + case STATUS_CONNECTED: + sStatus = "Connected"; + break; + case STATUS_OFFLINE: + sStatus = "Offline"; + break; + default: + sStatus = "UNKNOW"; + break; + } + out = Base::StringFormat("%s\t\t%s\t%s\t%s\n", hdi->connectKey.c_str(), sConn.c_str(), sStatus.c_str(), + hdi->devName.c_str()); + } else { + if (hdi->connStatus == STATUS_CONNECTED) { + out = Base::StringFormat("%s\n", hdi->connectKey.c_str()); + } + } +} + +string HdcServer::GetDaemonMapList(uint8_t opType) +{ + string ret; + bool fullDisplay = false; + if (OP_GET_STRLIST_FULL == opType) { + fullDisplay = true; + } + uv_rwlock_rdlock(&daemonAdmin); + map::iterator iter; + string echoLine; + for (iter = mapDaemon.begin(); iter != mapDaemon.end(); ++iter) { + HDaemonInfo di = iter->second; + if (!di) { + continue; + } + echoLine = ""; + BuildDaemonVisableLine(di, fullDisplay, echoLine); + ret += echoLine; + } + uv_rwlock_rdunlock(&daemonAdmin); + return ret; +} + +void HdcServer::GetDaemonMapOnlyOne(HDaemonInfo &hDaemonInfoInOut) +{ + uv_rwlock_rdlock(&daemonAdmin); + string key; + for (auto &i : mapDaemon) { + if (i.second->connStatus == STATUS_CONNECTED) { + if (key == STRING_EMPTY) { + key = i.first; + } else { + key = STRING_EMPTY; + break; + } + } + } + if (key.size() > 0) { + hDaemonInfoInOut = mapDaemon[key]; + } + uv_rwlock_rdunlock(&daemonAdmin); +} + +string HdcServer::AdminDaemonMap(uint8_t opType, const string &connectKey, HDaemonInfo &hDaemonInfoInOut) +{ + string sRet; + switch (opType) { + case OP_ADD: { + HDaemonInfo pdiNew = new HdcDaemonInformation(); + *pdiNew = *hDaemonInfoInOut; + uv_rwlock_wrlock(&daemonAdmin); + if (!mapDaemon[hDaemonInfoInOut->connectKey]) { + mapDaemon[hDaemonInfoInOut->connectKey] = pdiNew; + } + uv_rwlock_wrunlock(&daemonAdmin); + break; + } + case OP_GET_STRLIST: + case OP_GET_STRLIST_FULL: { + sRet = GetDaemonMapList(opType); + break; + } + case OP_QUERY: { + uv_rwlock_rdlock(&daemonAdmin); + if (mapDaemon.count(connectKey)) { + hDaemonInfoInOut = mapDaemon[connectKey]; + } + uv_rwlock_rdunlock(&daemonAdmin); + break; + } + case OP_REMOVE: { + uv_rwlock_wrlock(&daemonAdmin); + if (mapDaemon.count(connectKey)) { + mapDaemon.erase(connectKey); + } + uv_rwlock_wrunlock(&daemonAdmin); + break; + } + case OP_GET_ANY: { + uv_rwlock_rdlock(&daemonAdmin); + map::iterator iter; + for (iter = mapDaemon.begin(); iter != mapDaemon.end(); ++iter) { + HDaemonInfo di = iter->second; + // usb will be auto connected + if (di->connStatus == STATUS_READY || di->connStatus == STATUS_CONNECTED) { + hDaemonInfoInOut = di; + break; + } + } + uv_rwlock_rdunlock(&daemonAdmin); + break; + } + case OP_GET_ONLY: { + GetDaemonMapOnlyOne(hDaemonInfoInOut); + break; + } + case OP_UPDATE: { // Cannot update the Object HDi lower key value by direct value + uv_rwlock_wrlock(&daemonAdmin); + HDaemonInfo hdi = mapDaemon[hDaemonInfoInOut->connectKey]; + if (hdi) { + *mapDaemon[hDaemonInfoInOut->connectKey] = *hDaemonInfoInOut; + } + uv_rwlock_wrunlock(&daemonAdmin); + break; + } + default: + break; + } + return sRet; +} + +void HdcServer::NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) +{ + HDaemonInfo hdiOld = nullptr; + AdminDaemonMap(OP_QUERY, hSession->connectKey, hdiOld); + if (hdiOld == nullptr) { + return; + } + if (!freeOrClear) { // step1 + // update + HdcDaemonInformation diNew = *hdiOld; + diNew.connStatus = STATUS_OFFLINE; + HDaemonInfo hdiNew = &diNew; + AdminDaemonMap(OP_UPDATE, hSession->connectKey, hdiNew); + } else { // step2 + string usbMountPoint = hdiOld->usbMountPoint; + constexpr int waitDaemonReconnect = UV_DEFAULT_INTERVAL; // wait little time for daemon reinit + auto funcDelayUsbNotify = [this, usbMountPoint](const uint8_t flag, string &msg, const void *) -> void { + string s = usbMountPoint; + clsUSBClt->RemoveIgnoreDevice(s); + }; + if (usbMountPoint.size() > 0) { + // wait time for daemon reconnect + // If removed from maplist, the USB module will be reconnected, so it needs to wait for a while + Base::DelayDoSimple(&loopMain, waitDaemonReconnect, funcDelayUsbNotify); + } + } +} + +bool HdcServer::HandServerAuth(HSession hSession, SessionHandShake &handshake) +{ + bool ret = false; + int retChild = 0; + string bufString; + switch (handshake.authType) { + case AUTH_TOKEN: { + void *ptr = nullptr; + bool retChild = HdcAuth::KeylistIncrement(hSession->listKey, hSession->authKeyIndex, &ptr); + // HdcAuth::FreeKey will be effect at funciton 'FreeSession' + if (!retChild) { + // Iteration call certificate authentication + handshake.authType = AUTH_PUBLICKEY; + ret = HandServerAuth(hSession, handshake); + break; + } + char sign[BUF_SIZE_DEFAULT2] = { 0 }; + retChild = HdcAuth::AuthSign(ptr, (const unsigned char *)handshake.buf.c_str(), handshake.buf.size(), sign); + if (!retChild) { + break; + } + handshake.buf = string(sign, retChild); + handshake.authType = AUTH_SIGNATURE; + bufString = SerialStruct::SerializeToString(handshake); + Send(hSession->sessionId, 0, CMD_KERNEL_HANDSHAKE, (uint8_t *)bufString.c_str(), bufString.size()); + ret = true; + break; + } + case AUTH_PUBLICKEY: { + char bufPrivateKey[BUF_SIZE_DEFAULT2] = ""; + retChild = HdcAuth::GetPublicKeyFileBuf((unsigned char *)bufPrivateKey, sizeof(bufPrivateKey)); + if (!retChild) { + break; + } + handshake.buf = string(bufPrivateKey, retChild); + handshake.authType = AUTH_PUBLICKEY; + bufString = SerialStruct::SerializeToString(handshake); + Send(hSession->sessionId, 0, CMD_KERNEL_HANDSHAKE, (uint8_t *)bufString.c_str(), bufString.size()); + ret = true; + break; + } + default: + break; + } + return ret; +} + +bool HdcServer::ServerSessionHandshake(HSession hSession, uint8_t *payload, int payloadSize) +{ + // session handshake step3 + string s = string((char *)payload, payloadSize); + Hdc::HdcSessionBase::SessionHandShake handshake; + SerialStruct::ParseFromString(handshake, s); + if (handshake.banner != HANDSHAKE_MESSAGE.c_str()) { + WRITE_LOG(LOG_DEBUG, "Hello failed"); + return false; + } + if (handshake.authType != AUTH_OK) { + if (!HandServerAuth(hSession, handshake)) { + WRITE_LOG(LOG_DEBUG, "Auth failed"); + return false; + } + return true; + } + // handshake auth OK + HDaemonInfo hdiOld = nullptr; + AdminDaemonMap(OP_QUERY, hSession->connectKey, hdiOld); + if (!hdiOld) { + return false; + } + HdcDaemonInformation diNew = *hdiOld; + HDaemonInfo hdiNew = &diNew; + // update + hdiNew->connStatus = STATUS_CONNECTED; + if (handshake.buf.size() > sizeof(hdiNew->devName) || !handshake.buf.size()) { + hdiNew->devName = "unknow..."; + } else { + hdiNew->devName = handshake.buf; + } + AdminDaemonMap(OP_UPDATE, hSession->connectKey, hdiNew); + hSession->handshakeOK = true; + return true; +} + +bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, + const int payloadSize) +{ + bool ret = true; + HdcServerForClient *pSfc = static_cast(clsServerForClient); + // When you first initialize, ChannelID may be 0 + HChannel hChannel = pSfc->AdminChannel(OP_QUERY, channelId, nullptr); + if (CMD_KERNEL_HANDSHAKE == command) { + ret = ServerSessionHandshake(hSession, payload, payloadSize); + WRITE_LOG(LOG_DEBUG, "Session handshake %s", ret ? "successful" : "failed"); + return ret; + } + if (!hChannel) { + if (command == CMD_KERNEL_CHANNEL_CLOSE) { + // Daemon close channel and want to notify server close channel also, but it may has been + // closed by herself + } else { + // Client may be ctrl+c and Server remove channel. notify server async + } + Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); + return true; + } + switch (command) { + case CMD_KERNEL_ECHO_RAW: { // Native shell data output + pSfc->EchoClientRaw(channelId, payload, payloadSize); + break; + } + case CMD_KERNEL_ECHO: { + MessageLevel level = (MessageLevel)*payload; + string s(reinterpret_cast(payload + 1), payloadSize - 1); + pSfc->EchoClient(hChannel, level, s.c_str()); + WRITE_LOG(LOG_DEBUG, "CMD_KERNEL_ECHO size:%d", payloadSize - 1); + break; + } + case CMD_KERNEL_CHANNEL_CLOSE: { + WRITE_LOG(LOG_DEBUG, "CMD_KERNEL_CHANNEL_CLOSE channelid:%d", channelId); + ClearOwnTasks(hSession, channelId); + // Forcibly closing the tcp handle here may result in incomplete data reception on the client side + HdcServerForClient *sfc = static_cast(hChannel->clsChannel); + sfc->FreeChannel(hChannel->channelId); + if (*payload == 1) { + --(*payload); + Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, payload, 1); + } + break; + } + case CMD_FORWARD_SUCCESS: { + // add to local + HdcForwardInformation di; + HForwardInfo pdiNew = &di; + pdiNew->channelId = channelId; + pdiNew->sessionId = hSession->sessionId; + pdiNew->forwardDirection = ((char *)payload)[0] == '1'; + pdiNew->taskString = (char *)payload + 2; + AdminForwardMap(OP_ADD, STRING_EMPTY, pdiNew); + Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP); // detch client channel + break; + } + default: { + HSession hSession = AdminSession(OP_QUERY, hChannel->targetSessionId, nullptr); + if (!hSession) { + return false; + } + ret = DispatchTaskData(hSession, hChannel->channelId, command, payload, payloadSize); + break; + } + } + return ret; +} + +void HdcServer::BuildForwardVisableLine(bool fullOrSimble, HForwardInfo hfi, string &echo) +{ + string buf; + if (fullOrSimble) { + buf = Base::StringFormat("'%s'\t%s\n", hfi->taskString.c_str(), + hfi->forwardDirection ? "[Forward]" : "[Reverse]"); + } else { + buf = Base::StringFormat("%s\n", hfi->taskString.c_str()); + } + echo += buf; +} + +string HdcServer::AdminForwardMap(uint8_t opType, const string &taskString, HForwardInfo &hForwardInfoInOut) +{ + string sRet; + switch (opType) { + case OP_ADD: { + HForwardInfo pfiNew = new HdcForwardInformation(); + *pfiNew = *hForwardInfoInOut; + uv_rwlock_wrlock(&forwardAdmin); + if (!mapForward[hForwardInfoInOut->taskString]) { + mapForward[hForwardInfoInOut->taskString] = pfiNew; + } + uv_rwlock_wrunlock(&forwardAdmin); + break; + } + case OP_GET_STRLIST: + case OP_GET_STRLIST_FULL: { + uv_rwlock_rdlock(&forwardAdmin); + map::iterator iter; + for (iter = mapForward.begin(); iter != mapForward.end(); ++iter) { + HForwardInfo di = iter->second; + if (!di) { + continue; + } + BuildForwardVisableLine(opType == OP_GET_STRLIST_FULL, di, sRet); + } + uv_rwlock_rdunlock(&forwardAdmin); + break; + } + case OP_QUERY: { + uv_rwlock_rdlock(&forwardAdmin); + if (mapForward.count(taskString)) { + hForwardInfoInOut = mapForward[taskString]; + } + uv_rwlock_rdunlock(&forwardAdmin); + break; + } + case OP_REMOVE: { + uv_rwlock_wrlock(&forwardAdmin); + if (mapForward.count(taskString)) { + mapForward.erase(taskString); + } + uv_rwlock_wrunlock(&forwardAdmin); + break; + } + default: + break; + } + return sRet; +} + +void HdcServer::UsbPreConnect(uv_timer_t *handle) +{ + HSession hSession = (HSession)handle->data; + bool stopLoop = false; + HdcServer *hdcServer = (HdcServer *)hSession->classInstance; + const int usbConnectRetryMax = 5; + while (true) { + WRITE_LOG(LOG_DEBUG, "HdcServer::UsbPreConnect"); + if (++hSession->hUSB->retryCount > usbConnectRetryMax) { // max 15s + hdcServer->FreeSession(hSession->sessionId); + stopLoop = true; + break; + } + HDaemonInfo pDi = nullptr; + if (hSession->connectKey == "any") { + hdcServer->AdminDaemonMap(OP_GET_ANY, hSession->connectKey, pDi); + } else { + hdcServer->AdminDaemonMap(OP_QUERY, hSession->connectKey, pDi); + } + if (!pDi || !pDi->usbMountPoint.size()) { + break; + } + HdcHostUSB *hdcHostUSB = (HdcHostUSB *)hSession->classModule; + hdcHostUSB->ConnectDetectDaemon(hSession, pDi); + stopLoop = true; + break; + } + if (stopLoop && !uv_is_closing((const uv_handle_t *)handle)) { + uv_close((uv_handle_t *)handle, Base::CloseTimerCallback); + } +} + +// -1,has old,-2 error +int HdcServer::CreateConnect(const string &connectKey) +{ + uint8_t connType = 0; + if (connectKey.find(":") != std::string::npos) { // TCP + connType = CONN_TCP; + } else { // USB + connType = CONN_USB; + } + HDaemonInfo hdi = nullptr; + if (connectKey == "any") { + return RET_SUCCESS; + } + AdminDaemonMap(OP_QUERY, connectKey, hdi); + if (hdi == nullptr) { + HdcDaemonInformation di; + Base::ZeroStruct(di); + di.connectKey = connectKey; + di.connType = connType; + di.connStatus = STATUS_UNKNOW; + HDaemonInfo pDi = (HDaemonInfo)&di; + AdminDaemonMap(OP_ADD, "", pDi); + AdminDaemonMap(OP_QUERY, connectKey, hdi); + } + if (!hdi || hdi->connStatus == STATUS_CONNECTED) { + return ERR_GENERIC; + } + HSession hSession = nullptr; + if (CONN_TCP == connType) { + hSession = clsTCPClt->ConnectDaemon(connectKey); + } else { + hSession = MallocSession(true, CONN_USB, clsUSBClt); + hSession->connectKey = connectKey; + uv_timer_t *waitTimeDoCmd = new uv_timer_t; + uv_timer_init(&loopMain, waitTimeDoCmd); + waitTimeDoCmd->data = hSession; + uv_timer_start(waitTimeDoCmd, UsbPreConnect, 10, 100); + } + if (!hSession) { + return ERR_BUF_ALLOC; + } + HDaemonInfo hdiQuery = nullptr; + AdminDaemonMap(OP_QUERY, connectKey, hdiQuery); + if (hdiQuery) { + HdcDaemonInformation diNew = *hdiQuery; + diNew.hSession = hSession; + HDaemonInfo hdiNew = &diNew; + AdminDaemonMap(OP_UPDATE, hdiQuery->connectKey, hdiNew); + } + return RET_SUCCESS; +} + +void HdcServer::AttachChannel(HSession hSession, const uint32_t channelId) +{ + HdcServerForClient *hSfc = static_cast(clsServerForClient); + HChannel hChannel = hSfc->AdminChannel(OP_QUERY, channelId, nullptr); + int ret = 0; + if (!hChannel) { + return; + } + uv_tcp_init(&hSession->childLoop, &hChannel->hChildWorkTCP); + hChannel->hChildWorkTCP.data = hChannel; + hChannel->targetSessionId = hSession->sessionId; + if ((ret = uv_tcp_open((uv_tcp_t *)&hChannel->hChildWorkTCP, hChannel->fdChildWorkTCP)) < 0) { + WRITE_LOG(LOG_DEBUG, "Hdcserver AttachChannel uv_tcp_open failed %s, channelid:%d fdChildWorkTCP:%d", + uv_err_name(ret), hChannel->channelId, hChannel->fdChildWorkTCP); + Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP); + return; + } + Base::SetTcpOptions((uv_tcp_t *)&hChannel->hChildWorkTCP); + uv_read_start((uv_stream_t *)&hChannel->hChildWorkTCP, hSfc->AllocCallback, hSfc->ReadStream); +}; + +void HdcServer::DeatchChannel(HSession hSession, const uint32_t channelId) +{ + HdcServerForClient *hSfc = static_cast(clsServerForClient); + HChannel hChannel = hSfc->AdminChannel(OP_QUERY, channelId, nullptr); + if (!hChannel) { + return; + } + if (hChannel->childCleared) { + WRITE_LOG(LOG_DEBUG, "Childchannel has already freed, cid:%d", channelId); + return; + } + uint8_t count = 1; + Send(hSession->sessionId, hChannel->channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1); + if (uv_is_closing((const uv_handle_t *)&hChannel->hChildWorkTCP)) { + Base::DoNextLoop(&hSession->childLoop, hChannel, [](const uint8_t flag, string &msg, const void *data) { + HChannel hChannel = (HChannel)data; + hChannel->childCleared = true; + WRITE_LOG(LOG_DEBUG, "Childchannel free direct, cid:%d", hChannel->channelId); + }); + } else { + Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP, [](uv_handle_t *handle) -> void { + HChannel hChannel = (HChannel)handle->data; + hChannel->childCleared = true; + WRITE_LOG(LOG_DEBUG, "Childchannel free callback, cid:%d", hChannel->channelId); + }); + } +}; + +bool HdcServer::ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command, + uint8_t *bufPtr, const int size) +{ + HdcServerForClient *hSfc = static_cast(clsServerForClient); + HChannel hChannel = hSfc->AdminChannel(OP_QUERY, channelId, nullptr); + HSession hSession = AdminSession(OP_QUERY, sessionId, nullptr); + if (!hChannel || !hSession) { + return false; + } + return FetchCommand(hSession, channelId, command, bufPtr, size); +} + +// clang-format off +bool HdcServer::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, + const uint16_t command, uint8_t *payload, const int payloadSize) +// clang-format on +{ + bool ret = true; + hTaskInfo->ownerSessionClass = this; + switch (command) { + case CMD_UNITY_BUGREPORT_INIT: + case CMD_UNITY_BUGREPORT_DATA: + ret = TaskCommandDispatch(hTaskInfo, TYPE_UNITY, command, payload, payloadSize); + break; + case CMD_FILE_INIT: + case CMD_FILE_BEGIN: + case CMD_FILE_CHECK: + case CMD_FILE_DATA: + case CMD_FILE_FINISH: + ret = TaskCommandDispatch(hTaskInfo, TASK_FILE, command, payload, payloadSize); + break; + case CMD_FORWARD_INIT: + case CMD_FORWARD_CHECK: + case CMD_FORWARD_CHECK_RESULT: + case CMD_FORWARD_ACTIVE_MASTER: + case CMD_FORWARD_DATA: + case CMD_FORWARD_FREE_CONTEXT: + ret = TaskCommandDispatch(hTaskInfo, TASK_FORWARD, command, payload, payloadSize); + break; + case CMD_APP_INIT: + case CMD_APP_SIDELOAD: + case CMD_APP_BEGIN: + case CMD_APP_FINISH: + case CMD_APP_UNINSTALL: + ret = TaskCommandDispatch(hTaskInfo, TASK_APP, command, payload, payloadSize); + break; + case CMD_UPDATER_UPDATE_INIT: + case CMD_UPDATER_FLASH_INIT: + case CMD_UPDATER_CHECK: + case CMD_UPDATER_BEGIN: + case CMD_UPDATER_DATA: + case CMD_UPDATER_FINISH: + case CMD_UPDATER_ERASE: + case CMD_UPDATER_FORMAT: + case CMD_UPDATER_PROGRESS: + ret = TaskCommandDispatch(hTaskInfo, TASK_UPDATER, command, payload, payloadSize); + break; + default: + WRITE_LOG(LOG_WARN, "RedirectToTask error command:%d ", command); + ret = false; + break; + } + return ret; +} + +bool HdcServer::RemoveInstanceTask(const uint8_t op, HTaskInfo hTask) +{ + bool ret = true; + switch (hTask->taskType) { + case TYPE_SHELL: + WRITE_LOG(LOG_DEBUG, "Server not enable unity/shell"); + break; + case TYPE_UNITY: + ret = DoTaskRemove(hTask, op); + break; + case TASK_FILE: + ret = DoTaskRemove(hTask, op); + break; + case TASK_FORWARD: + ret = DoTaskRemove(hTask, op); + break; + case TASK_APP: + ret = DoTaskRemove(hTask, op); + break; + case TASK_UPDATER: + ret = DoTaskRemove(hTask, op); + break; + default: + ret = false; + break; + } + return ret; +} +} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/host/server.h b/services/flashd/host/server.h new file mode 100755 index 00000000..e1e66810 --- /dev/null +++ b/services/flashd/host/server.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_SERVER_H +#define HDC_SERVER_H +#include "host_common.h" + +namespace Hdc { +class HdcServer : public HdcSessionBase { +public: + HdcServer(bool serverOrDaemonIn); + virtual ~HdcServer(); + bool FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, + const int payloadSize); + string AdminDaemonMap(uint8_t opType, const string &connectKey, HDaemonInfo &hDaemonInfoInOut); + string AdminForwardMap(uint8_t opType, const string &taskString, HForwardInfo &hForwardInfoInOut); + int CreateConnect(const string &connectKey); + bool Initial(const char *listenString); + void AttachChannel(HSession hSession, const uint32_t channelId); + void DeatchChannel(HSession hSession, const uint32_t channelId); + static bool PullupServer(const char *listenString); + static void UsbPreConnect(uv_timer_t *handle); + void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear); + + HdcHostTCP *clsTCPClt; + HdcHostUSB *clsUSBClt; + void *clsServerForClient; + +private: + void ClearInstanceResource(); + void BuildDaemonVisableLine(HDaemonInfo hdi, bool fullDisplay, string &out); + void BuildForwardVisableLine(bool fullOrSimble, HForwardInfo hfi, string &echo); + void ClearMapDaemonInfo(); + bool ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command, uint8_t *bufPtr, + const int size); + bool RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, const uint16_t command, + uint8_t *payload, const int payloadSize); + bool RemoveInstanceTask(const uint8_t op, HTaskInfo hTask); + void BuildForwardVisableLine(HDaemonInfo hdi, char *out, int sizeOutBuf); + bool HandServerAuth(HSession hSession, SessionHandShake &handshake); + string GetDaemonMapList(uint8_t opType); + bool ServerSessionHandshake(HSession hSession, uint8_t *payload, int payloadSize); + void GetDaemonMapOnlyOne(HDaemonInfo &hDaemonInfoInOut); + void TryStopInstance(); + static bool PullupServerWin32(const char *path, const char *listenString); + + uv_rwlock_t daemonAdmin; + map mapDaemon; + uv_rwlock_t forwardAdmin; + map mapForward; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/host/server_for_client.cpp b/services/flashd/host/server_for_client.cpp new file mode 100755 index 00000000..fc6feb17 --- /dev/null +++ b/services/flashd/host/server_for_client.cpp @@ -0,0 +1,674 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "server_for_client.h" +#include "server.h" + +namespace Hdc { +HdcServerForClient::HdcServerForClient(const bool serverOrClient, const string &addrString, void *pClsServer, + uv_loop_t *loopMainIn) + : HdcChannelBase(serverOrClient, addrString, loopMainIn) +{ + clsServer = pClsServer; +} + +HdcServerForClient::~HdcServerForClient() +{ + WRITE_LOG(LOG_DEBUG, "~HdcServerForClient"); +} + +void HdcServerForClient::Stop() +{ + Base::TryCloseHandle((uv_handle_t *)&tcpListen); +} + +uint16_t HdcServerForClient::GetTCPListenPort() +{ + return channelPort; +} + +void HdcServerForClient::AcceptClient(uv_stream_t *server, int status) +{ + uv_tcp_t *pServTCP = (uv_tcp_t *)server; + HdcServerForClient *thisClass = (HdcServerForClient *)pServTCP->data; + HChannel hChannel = nullptr; + uint32_t uid = thisClass->MallocChannel(&hChannel); + if (!hChannel) { + return; + } + if (uv_accept(server, (uv_stream_t *)&hChannel->hWorkTCP) < 0) { + thisClass->FreeChannel(uid); + return; + } + WRITE_LOG(LOG_DEBUG, "HdcServerForClient acceptClient"); + // limit first recv + int bufMaxSize = 0; + uv_recv_buffer_size((uv_handle_t *)&hChannel->hWorkTCP, &bufMaxSize); + auto funcChannelHeaderAlloc = [](uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) -> void { + HChannel context = (HChannel)handle->data; + Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); + buf->base = (char *)context->ioBuf + context->availTailIndex; + buf->len = sizeof(struct ChannelHandShake) + DWORD_SERIALIZE_SIZE; // only recv static size + }; + // first packet static size, after this packet will be dup for normal recv + uv_read_start((uv_stream_t *)&hChannel->hWorkTCP, funcChannelHeaderAlloc, ReadStream); + // channel handshake step1 + struct ChannelHandShake handShake; + Base::ZeroStruct(handShake); + if (EOK == strcpy_s(handShake.banner, sizeof(handShake.banner), HANDSHAKE_MESSAGE.c_str())) { + handShake.channelId = htonl(hChannel->channelId); + thisClass->Send(hChannel->channelId, (uint8_t *)&handShake, sizeof(struct ChannelHandShake)); + } +} + +void HdcServerForClient::SetTCPListen() +{ + tcpListen.data = this; + struct sockaddr_in addr; + uv_tcp_init(loopMain, &tcpListen); + uv_ip4_addr(channelHost.c_str(), channelPort, &addr); + uv_tcp_bind(&tcpListen, (const struct sockaddr *)&addr, 0); + uv_listen((uv_stream_t *)&tcpListen, 128, (uv_connection_cb)AcceptClient); +} + +int HdcServerForClient::Initial() +{ + if (!clsServer) { + WRITE_LOG(LOG_FATAL, "Module client initial failed"); + return -1; + } + if (!channelHostPort.size() || !channelHost.size() || !channelPort) { + WRITE_LOG(LOG_FATAL, "Listen string initial failed"); + return -2; + } + SetTCPListen(); + return 0; +} + +void HdcServerForClient::EchoClient(HChannel hChannel, MessageLevel level, const char *msg, ...) +{ + string logInfo = ""; + switch (level) { + case MSG_FAIL: + logInfo = MESSAGE_FAIL; + break; + case MSG_INFO: + logInfo = MESSAGE_INFO; + break; + default: // successful, not append extra info + break; + } + va_list vaArgs; + va_start(vaArgs, msg); + string log = logInfo + Base::StringFormat(msg, vaArgs); + va_end(vaArgs); + if (log.back() != '\n') { + log += "\r\n"; + } + Send(hChannel->channelId, (uint8_t *)log.c_str(), log.size()); +} + +void HdcServerForClient::EchoClientRaw(const uint32_t channelId, uint8_t *payload, const int payloadSize) +{ + Send(channelId, payload, payloadSize); +} + +bool HdcServerForClient::SendToDaemon(HChannel hChannel, const uint16_t commandFlag, uint8_t *bufPtr, const int bufSize) +{ + HDaemonInfo hdi = nullptr; + bool ret = false; + HdcServer *ptrServer = (HdcServer *)clsServer; + while (true) { + ptrServer->AdminDaemonMap(OP_QUERY, hChannel->connectKey, hdi); + if (hdi == nullptr) { + break; + } + if (hdi->connStatus != STATUS_CONNECTED) { + break; + } + if (!hdi->hSession) { + break; + } + if (ptrServer->Send(hdi->hSession->sessionId, hChannel->channelId, commandFlag, bufPtr, bufSize) < 0) { + break; + } + ret = true; + break; + } + return ret; +} + +void HdcServerForClient::OrderFindTargets(HChannel hChannel) +{ + int count = 0; + EchoClient(hChannel, MSG_INFO, "Please add HDC server's firewall ruler to allow udp incoming, udpport:%d", + DEFAULT_PORT); + HdcServer *ptrServer = (HdcServer *)clsServer; + ptrServer->clsTCPClt->FindLanDaemon(); + list &lst = ptrServer->clsTCPClt->lstDaemonResult; + // refresh main list + HdcDaemonInformation di; + while (!lst.empty()) { + Base::ZeroStruct(di); + ++count; + di.connectKey = lst.front(); + di.connType = CONN_TCP; + di.connStatus = STATUS_READY; + HDaemonInfo pDi = (HDaemonInfo)&di; + ptrServer->AdminDaemonMap(OP_ADD, STRING_EMPTY, pDi); + lst.pop_front(); + } + EchoClient(hChannel, MSG_INFO, "Broadcast find daemon, total:%d", count); +#ifdef UNIT_TEST + string bufString = std::to_string(count); + Base::WriteBinFile((UT_TMP_PATH + "/base-discover.result").c_str(), (uint8_t *)bufString.c_str(), bufString.size(), + true); +#endif +} + +void HdcServerForClient::OrderConnecTargetResult(uv_timer_t *req) +{ + HChannel hChannel = (HChannel)req->data; + HdcServerForClient *thisClass = (HdcServerForClient *)hChannel->clsChannel; + HdcServer *ptrServer = (HdcServer *)thisClass->clsServer; + bool bConnectOK = false; + bool bExitRepet = false; + HDaemonInfo hdi = nullptr; + string sRet; + string target = std::string(hChannel->bufStd + 2); + if (target == "any") { + ptrServer->AdminDaemonMap(OP_GET_ANY, target, hdi); + } else { + ptrServer->AdminDaemonMap(OP_QUERY, target, hdi); + } + if (hdi && STATUS_CONNECTED == hdi->connStatus) { + bConnectOK = true; + } + while (true) { + if (bConnectOK) { + bExitRepet = true; + sRet = "Connect OK"; + thisClass->EchoClient(hChannel, MSG_OK, (char *)sRet.c_str()); + break; + } else { + uint16_t *bRetryCount = (uint16_t *)hChannel->bufStd; + ++(*bRetryCount); + if (*bRetryCount > 500) { + // 5s + bExitRepet = true; + sRet = "Connect failed"; + thisClass->EchoClient(hChannel, MSG_FAIL, (char *)sRet.c_str()); + break; + } + } + break; + } + if (bExitRepet) { + thisClass->FreeChannel(hChannel->channelId); + Base::TryCloseHandle((const uv_handle_t *)req, Base::CloseTimerCallback); + } +} + +bool HdcServerForClient::NewConnectTry(void *ptrServer, HChannel hChannel, const string &connectKey) +{ + int childRet = ((HdcServer *)ptrServer)->CreateConnect(connectKey); + bool ret = false; + if (-1 == childRet) { + EchoClient(hChannel, MSG_INFO, "Target is connected, repeat operation"); + } else if (-2 == childRet) { + EchoClient(hChannel, MSG_FAIL, "CreateConnect failed"); + WRITE_LOG(LOG_FATAL, "CreateConnect failed"); + } else { + Base::ZeroBuf(hChannel->bufStd, 2); + childRet = snprintf_s(hChannel->bufStd + 2, sizeof(hChannel->bufStd) - 2, sizeof(hChannel->bufStd) - 3, "%s", + (char *)connectKey.c_str()); + if (childRet > 0) { + Base::TimerUvTask(loopMain, hChannel, OrderConnecTargetResult, 10); + ret = true; + } + } + return ret; +} + +bool HdcServerForClient::CommandRemoveSession(HChannel hChannel, const char *connectKey) +{ + HdcServer *ptrServer = (HdcServer *)clsServer; + HDaemonInfo hdiOld = nullptr; + ((HdcServer *)ptrServer)->AdminDaemonMap(OP_QUERY, connectKey, hdiOld); + if (!hdiOld) { + EchoClient(hChannel, MSG_FAIL, "No target available"); + return false; + } + ((HdcServer *)ptrServer)->FreeSession(hdiOld->hSession->sessionId); + return true; +} + +bool HdcServerForClient::CommandRemoveForward(const string &forwardKey) +{ + HdcServer *ptrServer = (HdcServer *)clsServer; + HForwardInfo hfi = nullptr; + ptrServer->AdminForwardMap(OP_QUERY, forwardKey, hfi); + if (!hfi) { + return false; + } + HSession hSession = ptrServer->AdminSession(OP_QUERY, hfi->sessionId, nullptr); + if (!hSession) { + return false; + } + ptrServer->ClearOwnTasks(hSession, hfi->channelId); + FreeChannel(hfi->channelId); + hfi = nullptr; + ptrServer->AdminForwardMap(OP_REMOVE, forwardKey, hfi); + return true; +} + +void HdcServerForClient::GetTargetList(HChannel hChannel, void *formatCommandInput) +{ + TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput; + HdcServer *ptrServer = (HdcServer *)clsServer; + uint16_t cmd = OP_GET_STRLIST; + if (formatCommand->parameters == "v") { + cmd = OP_GET_STRLIST_FULL; + } + HDaemonInfo hdi = nullptr; + string sRet = ptrServer->AdminDaemonMap(cmd, STRING_EMPTY, hdi); + if (!sRet.length()) { + sRet = EMPTY_ECHO; + } + EchoClient(hChannel, MSG_OK, (char *)sRet.c_str()); +#ifdef UNIT_TEST + Base::WriteBinFile((UT_TMP_PATH + "/base-list.result").c_str(), (uint8_t *)MESSAGE_SUCCESS.c_str(), + MESSAGE_SUCCESS.size(), true); +#endif +} + +bool HdcServerForClient::GetAnyTarget(HChannel hChannel) +{ + HdcServer *ptrServer = (HdcServer *)clsServer; + HDaemonInfo hdi = nullptr; + ptrServer->AdminDaemonMap(OP_GET_ANY, STRING_EMPTY, hdi); + if (!hdi) { + EchoClient(hChannel, MSG_FAIL, "No target available"); + return false; + } + // can not use hdi->connectKey.This memory may be released to re-Malloc + string connectKey = hdi->connectKey; + bool ret = NewConnectTry(ptrServer, hChannel, connectKey); +#ifdef UNIT_TEST + Base::WriteBinFile((UT_TMP_PATH + "/base-any.result").c_str(), (uint8_t *)MESSAGE_SUCCESS.c_str(), + MESSAGE_SUCCESS.size(), true); +#endif + return ret; +} + +bool HdcServerForClient::RemoveForward(HChannel hChannel, const char *parameterString) +{ + HdcServer *ptrServer = (HdcServer *)clsServer; + if (parameterString == nullptr) { // remove all + HForwardInfo hfi = nullptr; // dummy + string echo = ptrServer->AdminForwardMap(OP_GET_STRLIST, "", hfi); + if (!echo.length()) { + return false; + } + vector filterStrings; + Base::SplitString(echo, string("\n"), filterStrings); + for (auto &&s : filterStrings) { + if (!CommandRemoveForward(s.c_str())) { + EchoClient(hChannel, MSG_FAIL, "Remove forward ruler failed,ruler:%s", s.c_str()); + } + } + } else { // remove single + if (!CommandRemoveForward(parameterString)) { + EchoClient(hChannel, MSG_FAIL, "Remove forward ruler failed,ruler:%s", parameterString); + } + } + return true; +} + +bool HdcServerForClient::DoCommandLocal(HChannel hChannel, void *formatCommandInput) +{ + TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput; + HdcServer *ptrServer = (HdcServer *)clsServer; + const char *parameterString = formatCommand->parameters.c_str(); + bool ret = false; + // Main thread command, direct Listen main thread + switch (formatCommand->cmdFlag) { + case CMD_KERNEL_TARGET_DISCOVER: { + OrderFindTargets(hChannel); + ret = false; + break; + } + case CMD_KERNEL_TARGET_LIST: { + GetTargetList(hChannel, formatCommandInput); + ret = false; + break; + } + case CMD_KERNEL_TARGET_ANY: { + ret = GetAnyTarget(hChannel); + break; + } + case CMD_KERNEL_TARGET_CONNECT: { + ret = NewConnectTry(ptrServer, hChannel, parameterString); + break; + } + case CMD_KERNEL_TARGET_DISCONNECT: { + CommandRemoveSession(hChannel, parameterString); + break; + } + case CMD_KERNEL_SERVER_KILL: { + WRITE_LOG(LOG_DEBUG, "Recv server kill command"); + uv_stop(loopMain); + ret = true; + break; + } + // task will be global task,Therefore, it can only be controlled in the global session. + case CMD_FORWARD_LIST: { + HForwardInfo hfi = nullptr; // dummy + string echo = ptrServer->AdminForwardMap(OP_GET_STRLIST_FULL, "", hfi); + if (!echo.length()) { + echo = EMPTY_ECHO; + } + EchoClient(hChannel, MSG_OK, (char *)echo.c_str()); + break; + } + case CMD_FORWARD_REMOVE: { + RemoveForward(hChannel, parameterString); + break; + } + case CMD_KERNEL_ENABLE_KEEPALIVE: { + // just use for 'list targets' now + hChannel->keepAlive = true; + ret = true; + break; + } + default: { + EchoClient(hChannel, MSG_FAIL, "ExecuteCommand need connect-key?"); + break; + } + } + return ret; +} + +bool HdcServerForClient::TaskCommand(HChannel hChannel, void *formatCommandInput) +{ + TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput; + HdcServer *ptrServer = (HdcServer *)clsServer; + int sizeSend = formatCommand->parameters.size(); + string cmdFlag; + uint8_t sizeCmdFlag = 0; + if (CMD_FILE_INIT == formatCommand->cmdFlag) { + cmdFlag = "send "; + sizeCmdFlag = 5; // 5: cmdFlag send size + } else if (CMD_FORWARD_INIT == formatCommand->cmdFlag) { + cmdFlag = "fport "; + sizeCmdFlag = 6; // 6: cmdFlag fport size + } else if (CMD_APP_INIT == formatCommand->cmdFlag) { + cmdFlag = "install "; + sizeCmdFlag = 8; // 8: cmdFlag install size + } else if (CMD_APP_UNINSTALL == formatCommand->cmdFlag) { + cmdFlag = "uninstall "; + sizeCmdFlag = 10; // 10: cmdFlag uninstall size + } else if (CMD_UNITY_BUGREPORT_INIT == formatCommand->cmdFlag) { + cmdFlag = "bugreport "; + sizeCmdFlag = 10; // 10: cmdFlag bugreport size + } else if (CMD_APP_SIDELOAD == formatCommand->cmdFlag) { + cmdFlag = "sideload "; + sizeCmdFlag = 9; // 9: cmdFlag sideload size + } else if (CMD_UPDATER_UPDATE_INIT == formatCommand->cmdFlag) { + cmdFlag = "update "; + sizeCmdFlag = 7; // 7: cmdFlag update size + } else if (CMD_UPDATER_FLASH_INIT == formatCommand->cmdFlag) { + cmdFlag = "flash "; + sizeCmdFlag = 6; // 6: cmdFlag flash size + } + uint8_t *payload = reinterpret_cast(const_cast(formatCommand->parameters.c_str())) + sizeCmdFlag; + if (!strncmp(formatCommand->parameters.c_str(), cmdFlag.c_str(), sizeCmdFlag)) { // local do + HSession hSession = FindAliveSession(hChannel->targetSessionId); + if (!hSession) { + return false; + } + ptrServer->DispatchTaskData(hSession, hChannel->channelId, formatCommand->cmdFlag, payload, + sizeSend - sizeCmdFlag); + } else { // Send to Daemon-side to do + SendToDaemon(hChannel, formatCommand->cmdFlag, payload, sizeSend - sizeCmdFlag); + } + return true; +} + +bool HdcServerForClient::DoCommandRemote(HChannel hChannel, void *formatCommandInput) +{ + TranslateCommand::FormatCommand *formatCommand = (TranslateCommand::FormatCommand *)formatCommandInput; + bool ret = false; + int sizeSend = formatCommand->parameters.size(); + string cmdFlag; + switch (formatCommand->cmdFlag) { + // Some simple commands only need to forward the instruction, no need to start Task + case CMD_SHELL_INIT: + case CMD_SHELL_DATA: + case CMD_UNITY_EXECUTE: + case CMD_UNITY_TERMINATE: + case CMD_UNITY_REMOUNT: + case CMD_UNITY_REBOOT: + case CMD_UNITY_RUNMODE: + case CMD_UNITY_HILOG: + case CMD_UNITY_ROOTRUN: + case CMD_UNITY_JPID: { + if (!SendToDaemon(hChannel, formatCommand->cmdFlag, + reinterpret_cast(const_cast(formatCommand->parameters.c_str())), + sizeSend)) { + break; + } + ret = true; + if (CMD_SHELL_INIT == formatCommand->cmdFlag) { + hChannel->interactiveShellMode = true; + } + break; + } + case CMD_FILE_INIT: + case CMD_FORWARD_INIT: + case CMD_APP_INIT: + case CMD_APP_UNINSTALL: + case CMD_UNITY_BUGREPORT_INIT: + case CMD_APP_SIDELOAD: + case CMD_UPDATER_UPDATE_INIT: + case CMD_UPDATER_FLASH_INIT: + case CMD_UPDATER_ERASE: + case CMD_UPDATER_FORMAT: { + TaskCommand(hChannel, formatCommandInput); + ret = true; + break; + } + default: + break; + } + if (!ret) { + EchoClient(hChannel, MSG_FAIL, "Failed to communicate with daemon"); + } + return ret; +} +// Do not specify Target's operations no longer need to put it in the thread. +bool HdcServerForClient::DoCommand(HChannel hChannel, void *formatCommandInput) +{ + bool ret = false; + if (!hChannel->hChildWorkTCP.loop) { + // Main thread command, direct Listen main thread + ret = DoCommandLocal(hChannel, formatCommandInput); + } else { // CONNECT DAEMON's work thread command, non-primary thread + ret = DoCommandRemote(hChannel, formatCommandInput); + } + return ret; +} + +// just call from BindChannelToSession +HSession HdcServerForClient::FindAliveSessionFromDaemonMap(const HChannel hChannel) +{ + HSession hSession = nullptr; + HDaemonInfo hdi = nullptr; + HdcServer *ptrServer = (HdcServer *)clsServer; + ptrServer->AdminDaemonMap(OP_QUERY, hChannel->connectKey, hdi); + if (!hdi) { + EchoClient(hChannel, MSG_FAIL, "Not match target founded, check connect-key please"); + return nullptr; + } + if (hdi->connStatus != STATUS_CONNECTED) { + EchoClient(hChannel, MSG_FAIL, "Device not founded or connected"); + return nullptr; + } + if (hdi->hSession->isDead) { + EchoClient(hChannel, MSG_FAIL, "Bind tartget session is dead"); + return nullptr; + } + hSession = (HSession)hdi->hSession; + return hSession; +} + +int HdcServerForClient::BindChannelToSession(HChannel hChannel, uint8_t *bufPtr, const int bytesIO) +{ + HSession hSession = nullptr; + if ((hSession = FindAliveSessionFromDaemonMap(hChannel)) == nullptr) { + return ERR_SESSION_NOFOUND; + } + bool isClosing = uv_is_closing((const uv_handle_t *)&hChannel->hWorkTCP); + if (!isClosing && (hChannel->fdChildWorkTCP = Base::DuplicateUvSocket(&hChannel->hWorkTCP)) < 0) { + WRITE_LOG(LOG_FATAL, "Duplicate socket failed, cid:%d", hChannel->channelId); + return ERR_SOCKET_DUPLICATE; + } + uv_close_cb funcWorkTcpClose = [](uv_handle_t *handle) -> void { + HChannel hChannel = (HChannel)handle->data; + --hChannel->sendRef; + }; + ++hChannel->sendRef; + if (!isClosing) { + uv_close((uv_handle_t *)&hChannel->hWorkTCP, funcWorkTcpClose); + } + Base::DoNextLoop(loopMain, hChannel, [](const uint8_t flag, string &msg, const void *data) { + // Thread message can avoid using thread lock and improve program efficiency + // If not next loop call, ReadStream will thread conflict + HChannel hChannel = (HChannel)data; + auto thisClass = (HdcServerForClient *)hChannel->clsChannel; + HSession hSession = nullptr; + if ((hSession = thisClass->FindAliveSessionFromDaemonMap(hChannel)) == nullptr) { + return; + } + auto ctrl = HdcSessionBase::BuildCtrlString(SP_ATTACH_CHANNEL, hChannel->channelId, nullptr, 0); + Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); + }); + return RET_SUCCESS; +} + +bool HdcServerForClient::CheckAutoFillTarget(HChannel hChannel) +{ + HdcServer *ptrServer = (HdcServer *)clsServer; + if (!hChannel->connectKey.size()) { + return false; // Operation of non-bound destination of scanning + } + if (hChannel->connectKey == CMDSTR_CONNECT_ANY) { + HDaemonInfo hdiOld = nullptr; + ptrServer->AdminDaemonMap(OP_GET_ONLY, "", hdiOld); + if (!hdiOld) { + return false; + } + hChannel->connectKey = hdiOld->connectKey; + return true; + } + return true; +} + +int HdcServerForClient::ChannelHandShake(HChannel hChannel, uint8_t *bufPtr, const int bytesIO) +{ + vector rebuildHandshake; + rebuildHandshake.insert(rebuildHandshake.end(), bufPtr, bufPtr + bytesIO); + rebuildHandshake.push_back(0x00); + struct ChannelHandShake *handShake = reinterpret_cast(rebuildHandshake.data()); + if (strncmp(handShake->banner, HANDSHAKE_MESSAGE.c_str(), HANDSHAKE_MESSAGE.size())) { + hChannel->availTailIndex = 0; + WRITE_LOG(LOG_DEBUG, "Channel Hello failed"); + return ERR_HANDSHAKE_NOTMATCH; + } + if (strlen(handShake->connectKey) > sizeof(handShake->connectKey)) { + hChannel->availTailIndex = 0; + WRITE_LOG(LOG_DEBUG, "Connectkey's size incorrect"); + return ERR_HANDSHAKE_CONNECTKEY_FAILED; + } + // channel handshake step3 + WRITE_LOG(LOG_DEBUG, "ServerForClient channel handshake finished"); + hChannel->connectKey = handShake->connectKey; + hChannel->handshakeOK = true; + if (!CheckAutoFillTarget(hChannel)) { + return 0; + } + // channel handshake stBindChannelToSession + if (BindChannelToSession(hChannel, nullptr, 0)) { + hChannel->availTailIndex = 0; + WRITE_LOG(LOG_FATAL, "BindChannelToSession failed"); + return ERR_GENERIC; + } + return 0; +} + +// Here is Server to get data, the source is the SERVER's ChildWork to send data +int HdcServerForClient::ReadChannel(HChannel hChannel, uint8_t *bufPtr, const int bytesIO) +{ + int ret = 0; + if (!hChannel->handshakeOK) { + return ChannelHandShake(hChannel, bufPtr, bytesIO); + } + struct TranslateCommand::FormatCommand formatCommand = { 0 }; + if (!hChannel->interactiveShellMode) { + string retEcho = String2FormatCommand((char *)bufPtr, bytesIO, &formatCommand); + if (retEcho.length()) { + if (!strcmp((char *)bufPtr, CMDSTR_SOFTWARE_HELP.c_str()) || + !strcmp((char *)bufPtr, CMDSTR_SOFTWARE_VERSION.c_str()) || + !strcmp((char *)bufPtr, "flash")) { + EchoClient(hChannel, MSG_OK, retEcho.c_str()); + } else { + EchoClient(hChannel, MSG_FAIL, retEcho.c_str()); + } + } + if (formatCommand.bJumpDo) { + ret = -10; + return ret; + } + } else { + formatCommand.parameters = string(reinterpret_cast(bufPtr), bytesIO); + formatCommand.cmdFlag = CMD_SHELL_DATA; + } + if (!DoCommand(hChannel, &formatCommand)) { + return -3; // -3: error or want close + } + ret = bytesIO; + return ret; +}; + +// avoid session dead +HSession HdcServerForClient::FindAliveSession(uint32_t sessionId) +{ + HdcServer *ptrServer = (HdcServer *)clsServer; + HSession hSession = ptrServer->AdminSession(OP_QUERY, sessionId, nullptr); + if (!hSession || hSession->isDead) { + return nullptr; + } else { + return hSession; + } +} + +bool HdcServerForClient::ChannelSendSessionCtrlMsg(vector &ctrlMsg, uint32_t sessionId) +{ + HSession hSession = FindAliveSession(sessionId); + if (!hSession) { + return false; + } + return Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrlMsg.data(), ctrlMsg.size()) > 0; +} +} // namespace Hdc diff --git a/services/flashd/host/server_for_client.h b/services/flashd/host/server_for_client.h new file mode 100755 index 00000000..22ca06e2 --- /dev/null +++ b/services/flashd/host/server_for_client.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_SERVERFORCLIENT_H +#define HDC_SERVERFORCLIENT_H +#include "host_common.h" +#include "translate.h" + +namespace Hdc { +class HdcServerForClient : public HdcChannelBase { +public: + HdcServerForClient(const bool serverOrClient, const string &addrString, void *pClsServer, uv_loop_t *loopMainIn); + virtual ~HdcServerForClient(); + int Initial(); + void EchoClient(HChannel hChannel, MessageLevel level, const char *msg, ...); + void EchoClientRaw(const uint32_t channelId, uint8_t *payload, const int payloadSize); + uint16_t GetTCPListenPort(); + void Stop(); + +protected: +private: + static void AcceptClient(uv_stream_t *server, int status); + void SetTCPListen(); + int ReadChannel(HChannel hChannel, uint8_t *bufPtr, const int bytesIO); + bool DoCommand(HChannel hChannel, void *formatCommandInput); + void OrderFindTargets(HChannel hChannel); + bool NewConnectTry(void *ptrServer, HChannel hChannel, const string &connectKey); + static void OrderConnecTargetResult(uv_timer_t *req); + bool SendToDaemon(HChannel hChannel, const uint16_t commandFlag, uint8_t *bufPtr, const int bufSize); + int BindChannelToSession(HChannel hChannel, uint8_t *bufPtr, const int bytesIO); + bool CheckAutoFillTarget(HChannel hChannel); + bool CommandRemoveSession(HChannel hChannel, const char *connectKey); + bool CommandRemoveForward(const string &forwardKey); + bool DoCommandLocal(HChannel hChannel, void *formatCommandInput); + bool DoCommandRemote(HChannel hChannel, void *formatCommandInput); + void GetTargetList(HChannel hChannel, void *formatCommandInput); + bool GetAnyTarget(HChannel hChannel); + bool RemoveForward(HChannel hChannel, const char *parameterString); + bool TaskCommand(HChannel hChannel, void *formatCommandInput); + int ChannelHandShake(HChannel hChannel, uint8_t *bufPtr, const int bytesIO); + bool ChannelSendSessionCtrlMsg(vector &ctrlMsg, uint32_t sessionId); + HSession FindAliveSession(uint32_t sessionId); + HSession FindAliveSessionFromDaemonMap(const HChannel hChannel); + + uv_tcp_t tcpListen; + void *clsServer; +}; +} // namespace Hdc +#endif \ No newline at end of file diff --git a/services/flashd/host/translate.cpp b/services/flashd/host/translate.cpp new file mode 100755 index 00000000..350765eb --- /dev/null +++ b/services/flashd/host/translate.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 "translate.h" + +namespace Hdc { +namespace TranslateCommand { + string Usage() + { + string ret; + + ret = "\n OpenHarmony flash ...\n\n" + "---------------------------------global commands:----------------------------------\n" + " -h/help - Print flashd help\n" + " -v/version - Print flashd version\n" + " -l 0-5 - Set runtime loglevel\n" + " -t connectkey - Use device with given connect key\n" + "\n" + "---------------------------------component commands:-------------------------------\n" + "session commands(on server):\n" + " discover - Discover devices listening on TCP via LAN broadcast\n" + " list targets [-v] - List all devices status, -v for detail\n" + " tconn key - Connect device via key, TCP use ip:port\n" + " example:192.168.0.100:10178/192.168.0.100\n" + " USB connect automatic, TCP need to connect manually\n" + " start [-r] - Start server. If with '-r', will be restart server\n" + " kill [-r] - Kill server. If with '-r', will be restart server\n" + " -s [ip:]port - Set flash server listen config\n" + "\n" + "service commands(on daemon):\n" + " target boot [-bootloader|-recovery] - Reboot the device or boot into bootloader\\recovery.\n" + " tmode usb - Reboot the device, listening on USB\n" + " tmode port [port] - Reboot the device, listening on TCP port\n" + "\n" + "---------------------------------flash commands:-------------------------------------\n" + "flash commands:\n" + " update packagename - Update system by package\n" + " flash [-f] partition imagename - Flash partition by image\n" + " erase [-f] partition - Erase partition\n" + " format [-f] partition -t fs_type - Format partition -t [ext4 | f2fs]\n"; + return ret; + } + + string TargetConnect(FormatCommand *outCmd) + { + string stringError; + if (Base::StringEndsWith(outCmd->parameters, " -remove")) { + outCmd->parameters = outCmd->parameters.substr(0, outCmd->parameters.size() - 8); + outCmd->cmdFlag = CMD_KERNEL_TARGET_DISCONNECT; + } else { + outCmd->cmdFlag = CMD_KERNEL_TARGET_CONNECT; + if (outCmd->parameters.size() > 22) { // 22: tcp max=21,USB max=8bytes + stringError = "Error connect key's size"; + outCmd->bJumpDo = true; + } + } + if (outCmd->parameters.find(":") != std::string::npos) { + // tcp mode + string ip = outCmd->parameters.substr(0, outCmd->parameters.find(":")); + string sport = outCmd->parameters.substr(outCmd->parameters.find(":") + 1); + int port = std::stoi(sport); + sockaddr_in addr; + if ((port <= 0 || port > MAX_IP_PORT) || uv_ip4_addr(ip.c_str(), port, &addr) < 0) { + stringError = "IP:Port incorrect"; + outCmd->bJumpDo = true; + } + } + return stringError; + } + + string ForwardPort(const char *input, FormatCommand *outCmd) + { + string stringError; + const char *pExtra = input + 6; // CMDSTR_FORWARD_FPORT CMDSTR_FORWARD_RPORT + " " size + if (!strcmp(pExtra, "ls")) { + outCmd->cmdFlag = CMD_FORWARD_LIST; + } else if (!strncmp(pExtra, "rm", 2)) { // 2 rm size + outCmd->cmdFlag = CMD_FORWARD_REMOVE; + if (strcmp(pExtra, "rm")) { + outCmd->parameters = input + 9; // 9 rm extra size + } + } else { + const char *p = input + 6; + // clang-format off + if (strncmp(p, "tcp:", 4) && strncmp(p, "localabstract:", 14) && strncmp(p, "localreserved:", 14) && + strncmp(p, "localfilesystem:", 16) && strncmp(p, "dev:", 4) && strncmp(p, "jdwp:", 5)) { + stringError = "Incorrect forward command"; + outCmd->bJumpDo = true; + } + // clang-format on + outCmd->cmdFlag = CMD_FORWARD_INIT; + outCmd->parameters = input; + } + return stringError; + } + + string RunMode(const char *input, FormatCommand *outCmd) + { + string stringError; + outCmd->cmdFlag = CMD_UNITY_RUNMODE; + outCmd->parameters = input + CMDSTR_TARGET_MODE.size() + 1; // with ' ' + if (!strncmp(outCmd->parameters.c_str(), "port", 4) + && !strcmp(outCmd->parameters.c_str(), CMDSTR_TMODE_USB.c_str())) { + stringError = "Error tmode command"; + outCmd->bJumpDo = true; + } else if (!strncmp(outCmd->parameters.c_str(), "port ", 5)) { + int port = atoi(input + 4); + if (port > MAX_IP_PORT || port <= 0) { + stringError = "Incorrect port range"; + outCmd->bJumpDo = true; + } + } + return stringError; + } + + string TargetReboot(const char *input, FormatCommand *outCmd) + { + string stringError; + outCmd->cmdFlag = CMD_UNITY_REBOOT; + if (strcmp(input, CMDSTR_TARGET_REBOOT.c_str())) { + outCmd->parameters = input + 12; + if (outCmd->parameters != "-bootloader" + && outCmd->parameters != "-recovery" && outCmd->parameters != "-flashd") { + stringError = "Error reboot paramenter"; + outCmd->bJumpDo = true; + } else { + outCmd->parameters.erase(outCmd->parameters.begin()); + } + } + return stringError; + } + + // command input + // client side:Enter string data formatting conversion to module see internal processing command + string String2FormatCommand(const char *inputRaw, int sizeInputRaw, FormatCommand *outCmd) + { + string stringError; + string input = string(inputRaw, sizeInputRaw); + if (!strcmp(input.c_str(), CMDSTR_SOFTWARE_HELP.c_str())) { + outCmd->cmdFlag = CMD_KERNEL_HELP; + stringError = Usage(); + outCmd->bJumpDo = true; + } else if (!strcmp(input.c_str(), CMDSTR_SOFTWARE_VERSION.c_str())) { + outCmd->cmdFlag = CMD_KERNEL_HELP; + stringError = Base::GetVersion(); + outCmd->bJumpDo = true; + } else if (!strcmp(input.c_str(), CMDSTR_TARGET_DISCOVER.c_str())) { + outCmd->cmdFlag = CMD_KERNEL_TARGET_DISCOVER; + } else if (!strncmp(input.c_str(), CMDSTR_LIST_TARGETS.c_str(), CMDSTR_LIST_TARGETS.size())) { + outCmd->cmdFlag = CMD_KERNEL_TARGET_LIST; + if (strstr(input.c_str(), " -v")) { + outCmd->parameters = "v"; + } + } else if (!strcmp(input.c_str(), CMDSTR_CONNECT_ANY.c_str())) { + outCmd->cmdFlag = CMD_KERNEL_TARGET_ANY; + } else if (!strncmp(input.c_str(), CMDSTR_CONNECT_TARGET.c_str(), CMDSTR_CONNECT_TARGET.size())) { + outCmd->parameters = input.c_str() + CMDSTR_CONNECT_TARGET.size() + 1; // with ' ' + stringError = TargetConnect(outCmd); + } else if (!strncmp(input.c_str(), (CMDSTR_SHELL + " ").c_str(), CMDSTR_SHELL.size() + 1)) { + outCmd->cmdFlag = CMD_UNITY_EXECUTE; + outCmd->parameters = input.c_str() + CMDSTR_SHELL.size() + 1; + } else if (!strcmp(input.c_str(), CMDSTR_SHELL.c_str())) { + outCmd->cmdFlag = CMD_SHELL_INIT; + } else if (!strncmp(input.c_str(), CMDSTR_FILE_SEND.c_str(), CMDSTR_FILE_SEND.size()) + || !strncmp(input.c_str(), CMDSTR_FILE_RECV.c_str(), CMDSTR_FILE_RECV.size())) { + outCmd->cmdFlag = CMD_FILE_INIT; + outCmd->parameters = input.c_str() + 5; // 5: CMDSTR_FORWARD_FPORT CMDSTR_FORWARD_RPORT size + } else if (!strncmp(input.c_str(), string(CMDSTR_FORWARD_FPORT + " ").c_str(), CMDSTR_FORWARD_FPORT.size() + 1) + || !strncmp(input.c_str(), string(CMDSTR_FORWARD_RPORT + " ").c_str(), + CMDSTR_FORWARD_RPORT.size() + 1)) { + stringError = ForwardPort(input.c_str(), outCmd); + } else if (!strcmp(input.c_str(), CMDSTR_KILL_SERVER.c_str())) { + outCmd->cmdFlag = CMD_KERNEL_SERVER_KILL; + } else if (!strcmp(input.c_str(), CMDSTR_KILL_DAEMON.c_str())) { + outCmd->cmdFlag = CMD_UNITY_TERMINATE; + outCmd->parameters = "0"; + } else if (!strncmp(input.c_str(), CMDSTR_APP_INSTALL.c_str(), CMDSTR_APP_INSTALL.size())) { + outCmd->cmdFlag = CMD_APP_INIT; + outCmd->parameters = input; + } else if (!strncmp(input.c_str(), CMDSTR_APP_UNINSTALL.c_str(), CMDSTR_APP_UNINSTALL.size())) { + outCmd->cmdFlag = CMD_APP_UNINSTALL; + outCmd->parameters = input; + if (outCmd->parameters.size() > 512 || outCmd->parameters.size() < 4) { + stringError = "Package's path incorrect"; + outCmd->bJumpDo = true; + } + } else if (!strcmp(input.c_str(), CMDSTR_TARGET_MOUNT.c_str())) { + outCmd->cmdFlag = CMD_UNITY_REMOUNT; + } else if (!strcmp(input.c_str(), CMDSTR_LIST_JDWP.c_str())) { + outCmd->cmdFlag = CMD_UNITY_JPID; + } else if (!strncmp(input.c_str(), CMDSTR_TARGET_REBOOT.c_str(), CMDSTR_TARGET_REBOOT.size())) { + TargetReboot(input.c_str(), outCmd); + } else if (!strncmp(input.c_str(), CMDSTR_TARGET_MODE.c_str(), CMDSTR_TARGET_MODE.size())) { + RunMode(input.c_str(), outCmd); + } else if (!strcmp(input.c_str(), CMDSTR_CONNECT_ANY.c_str())) { + outCmd->cmdFlag = CMD_KERNEL_TARGET_ANY; + } else if (!strncmp(input.c_str(), CMDSTR_HILOG.c_str(), CMDSTR_HILOG.size())) { + outCmd->cmdFlag = CMD_UNITY_HILOG; + if (strstr(input.c_str(), " -v")) { + outCmd->parameters = "v"; + } + } else if (!strncmp(input.c_str(), CMDSTR_STARTUP_MODE.c_str(), CMDSTR_STARTUP_MODE.size())) { + outCmd->cmdFlag = CMD_UNITY_ROOTRUN; + if (strstr(input.c_str(), " -r")) { + outCmd->parameters = "r"; + } + } else if (!strncmp(input.c_str(), CMDSTR_APP_SIDELOAD.c_str(), CMDSTR_APP_SIDELOAD.size())) { + if (strlen(input.c_str()) == CMDSTR_APP_SIDELOAD.size()) { + stringError = "Incorrect command, please with local path"; + outCmd->bJumpDo = true; + } + outCmd->cmdFlag = CMD_APP_SIDELOAD; + outCmd->parameters = input; + } else if (!strncmp(input.c_str(), CMDSTR_BUGREPORT.c_str(), CMDSTR_BUGREPORT.size())) { + outCmd->cmdFlag = CMD_UNITY_BUGREPORT_INIT; + outCmd->parameters = input; + if (outCmd->parameters.size() == CMDSTR_BUGREPORT.size()) { + outCmd->parameters += " "; + } + } + // Inner command, protocol uses only + else if (input == CMDSTR_INNER_ENABLE_KEEPALIVE) { + outCmd->cmdFlag = CMD_KERNEL_ENABLE_KEEPALIVE; + } else if (HostUpdater::CheckMatchUpdate(input, stringError, outCmd->cmdFlag, outCmd->bJumpDo)) { + outCmd->parameters = input; + } else { + stringError = "Unknown command..."; + outCmd->bJumpDo = true; + } + // nl + if (stringError.size()) { + stringError += "\n"; + } + return stringError; + }; +} +} // namespace Hdc diff --git a/services/flashd/host/translate.h b/services/flashd/host/translate.h new file mode 100755 index 00000000..96128e50 --- /dev/null +++ b/services/flashd/host/translate.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef HDC_TRANSLATE_H +#define HDC_TRANSLATE_H +#include "host_common.h" + +namespace Hdc { +namespace TranslateCommand { + struct FormatCommand { + uint16_t cmdFlag; + string parameters; + bool bJumpDo; + }; + + string String2FormatCommand(const char *inputRaw, int sizeInputRaw, FormatCommand *outCmd); + string Usage(); +} +} +#endif \ No newline at end of file diff --git a/services/updater_binary/main.cpp b/services/updater_binary/main.cpp index 62542a9b..10ccdd89 100644 --- a/services/updater_binary/main.cpp +++ b/services/updater_binary/main.cpp @@ -44,4 +44,4 @@ int main(int argc, char **argv) std::string packagePath = argv[0]; return ProcessUpdater(retry, pipeFd, packagePath, utils::GetCertName()); } -#endif \ No newline at end of file +#endif diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 5a7a54c8..80172c3f 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -44,8 +44,8 @@ ohos_unittest("updater_unittest") { "applypatch_test/transfer_manager_unittest.cpp", "diffpatch/bzip2_unittest.cpp", "diffpatch/diffpatch_unittest.cpp", - "flashd_test/flash_host_unittest.cpp", "flashd_test/flash_service_unittest.cpp", + "flashd_test/flash_host_unittest.cpp", "fs_manager/do_partition_unittest.cpp", "log_test/log_unittest.cpp", "misc_info_test/misc_info_unittest.cpp", @@ -96,8 +96,8 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/flashd/blockdevice.cpp", "//base/update/updater/services/flashd/daemon/daemon_updater.cpp", "//base/update/updater/services/flashd/daemon/flashd_main.cpp", - "//base/update/updater/services/flashd/flash_service.cpp", "//base/update/updater/services/flashd/host/host_updater.cpp", + "//base/update/updater/services/flashd/flash_service.cpp", "//base/update/updater/services/flashd/partition.cpp", "//base/update/updater/services/fs_manager/cmp_partition.cpp", "//base/update/updater/services/fs_manager/do_partition.cpp", @@ -167,6 +167,7 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/flashd", "//base/update/updater/services/flashd/daemon", "//base/update/updater/services/flashd/host", + "//base/update/updater/services/flashd/common", "//base/update/updater/services/fs_manager", "//base/update/updater/services/applypatch", "//base/update/updater/services/diffpatch", @@ -196,10 +197,6 @@ ohos_unittest("updater_unittest") { "//drivers/peripheral/input/hal/include", "//drivers/peripheral/input/interfaces/include", "//third_party/bounds_checking_function/include", - "//developtools/hdc_standard/src", - "//developtools/hdc_standard/src/daemon", - "//developtools/hdc_standard/src/common", - "//developtools/hdc_standard/src/host", "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ @@ -214,7 +211,7 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/package:libupdaterpackage", "//base/update/updater/services/ui:libui", "//base/update/updater/utils:libutils", - "//developtools/hdc_standard:hdc_deamon_flashd", + "//base/update/updater/services/flashd:flashd_deamon", "//third_party/bounds_checking_function:libsec_static", "//third_party/bzip2:libbz2", "//third_party/cJSON:cjson_static", diff --git a/test/unittest/flashd_test/flash_host_unittest.cpp b/test/unittest/flashd_test/flash_host_unittest.cpp index 0b9c580f..36561822 100755 --- a/test/unittest/flashd_test/flash_host_unittest.cpp +++ b/test/unittest/flashd_test/flash_host_unittest.cpp @@ -172,12 +172,6 @@ HWTEST_F(FLashHostUnitTest, TestFlashHostFlash, TestSize.Level1) EXPECT_EQ(0, test.TestFlashProgress(CMD_UPDATER_FLASH_INIT, cmdParam, 100)); } -HWTEST_F(FLashHostUnitTest, TestFlashHostHelp, TestSize.Level1) -{ - std::string help = HostUpdater::GetFlashdHelp(); - printf("%s", help.c_str()); -} - HWTEST_F(FLashHostUnitTest, TestFlashHostMatch, TestSize.Level1) { std::string stringError; diff --git a/utils/utils.cpp b/utils/utils.cpp index fe205e4b..3da6a9a1 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -190,6 +190,8 @@ void DoReboot(const std::string& rebootTarget, const std::string &extData) result = strcpy_s(msg.update, MAX_UPDATE_SIZE - 1, extData.c_str()); UPDATER_ERROR_CHECK(result == 0, "Failed to copy update", return); msg.update[MAX_UPDATE_SIZE - 1] = 0; + } else { + UPDATER_ERROR_CHECK(!memset_s(msg.update, MAX_UPDATE_SIZE, 0, MAX_UPDATE_SIZE), "Memset_s failed", return); } if (WriteUpdaterMessage(miscBlockDevice, msg) != true) { LOG(INFO) << "DoReboot: WriteUpdaterMessage boot_updater error"; -- Gitee From 15c80870e00debc0483adfc088ba9db770a7c35d Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Tue, 16 Nov 2021 14:03:01 +0800 Subject: [PATCH 53/94] updater: fix gn format Signed-off-by: xionglei6 --- services/flashd/BUILD.gn | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn index d0019f88..3933ab11 100755 --- a/services/flashd/BUILD.gn +++ b/services/flashd/BUILD.gn @@ -172,12 +172,12 @@ ohos_executable("ohflash") { "${FLASHD_HDC_PATH}/host/host_forward.cpp", "${FLASHD_HDC_PATH}/host/host_tcp.cpp", "${FLASHD_HDC_PATH}/host/host_unity.cpp", + "${FLASHD_HDC_PATH}/host/host_updater.cpp", "${FLASHD_HDC_PATH}/host/host_usb.cpp", "${FLASHD_HDC_PATH}/host/main.cpp", "${FLASHD_HDC_PATH}/host/server.cpp", "${FLASHD_HDC_PATH}/host/server_for_client.cpp", "${FLASHD_HDC_PATH}/host/translate.cpp", - "${FLASHD_HDC_PATH}/host/host_updater.cpp", ] sources += common_sources @@ -189,9 +189,7 @@ ohos_executable("ohflash") { "//utils/native/base:utilsecurec", ] - deps += [ - "//third_party/libusb:libusb", - ] + deps += [ "//third_party/libusb:libusb" ] include_dirs = [ "${FLASHD_HDC_PATH}/host", @@ -201,14 +199,14 @@ ohos_executable("ohflash") { "//third_party/libuv", ] - if(is_mingw) { + if (is_mingw) { static_link = true defines += [ "_WIN32" ] defines += [ "WIN32_LEAN_AND_MEAN" ] libs += [ "setupapi" ] } - if(is_linux) { + if (is_linux) { static_link = true deps += [ "//third_party/openssl:libcrypto_static" ] } @@ -217,23 +215,16 @@ ohos_executable("ohflash") { part_name = "updater" } - group("flashhost_target_standard") { - deps = [ - ":ohflash", - ] + deps = [ ":ohflash" ] } group("flashhost_target_standard_linux") { - deps = [ - ":ohflash(//build/toolchain/linux:clang_x64)", - ] + deps = [ ":ohflash(//build/toolchain/linux:clang_x64)" ] } group("flashhost_target_standard_mingw") { - deps = [ - ":ohflash(//build/toolchain/mingw:mingw_x86_64)", - ] + deps = [ ":ohflash(//build/toolchain/mingw:mingw_x86_64)" ] } group("flashhost_target_standard_all") { -- Gitee From 4f8fff9a6b8d042d0b8abb549a8571990ec8de46 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Tue, 16 Nov 2021 14:54:13 +0800 Subject: [PATCH 54/94] updater: fix gn format Signed-off-by: xionglei6 --- test/unittest/BUILD.gn | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 80172c3f..8fd94283 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -44,8 +44,8 @@ ohos_unittest("updater_unittest") { "applypatch_test/transfer_manager_unittest.cpp", "diffpatch/bzip2_unittest.cpp", "diffpatch/diffpatch_unittest.cpp", - "flashd_test/flash_service_unittest.cpp", "flashd_test/flash_host_unittest.cpp", + "flashd_test/flash_service_unittest.cpp", "fs_manager/do_partition_unittest.cpp", "log_test/log_unittest.cpp", "misc_info_test/misc_info_unittest.cpp", @@ -96,8 +96,8 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/flashd/blockdevice.cpp", "//base/update/updater/services/flashd/daemon/daemon_updater.cpp", "//base/update/updater/services/flashd/daemon/flashd_main.cpp", - "//base/update/updater/services/flashd/host/host_updater.cpp", "//base/update/updater/services/flashd/flash_service.cpp", + "//base/update/updater/services/flashd/host/host_updater.cpp", "//base/update/updater/services/flashd/partition.cpp", "//base/update/updater/services/fs_manager/cmp_partition.cpp", "//base/update/updater/services/fs_manager/do_partition.cpp", @@ -206,12 +206,12 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/applypatch:libapplypatch", "//base/update/updater/services/diffpatch/diff:libdiff", "//base/update/updater/services/diffpatch/patch:libpatch", + "//base/update/updater/services/flashd:flashd_deamon", "//base/update/updater/services/fs_manager:libfsmanager", "//base/update/updater/services/log:libupdaterlog", "//base/update/updater/services/package:libupdaterpackage", "//base/update/updater/services/ui:libui", "//base/update/updater/utils:libutils", - "//base/update/updater/services/flashd:flashd_deamon", "//third_party/bounds_checking_function:libsec_static", "//third_party/bzip2:libbz2", "//third_party/cJSON:cjson_static", -- Gitee From fb0e7fbabac16404edeb22e1232062e62f30952c Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Wed, 17 Nov 2021 10:26:23 +0800 Subject: [PATCH 55/94] flashed Signed-off-by: xionglei6 --- services/flashd/BUILD.gn | 90 +- services/flashd/common/async_cmd.cpp | 189 --- services/flashd/common/async_cmd.h | 64 - services/flashd/common/auth.cpp | 488 ------ services/flashd/common/auth.h | 37 - services/flashd/common/base.h | 146 -- services/flashd/common/channel.cpp | 434 ------ services/flashd/common/channel.h | 76 - services/flashd/common/common.h | 79 - services/flashd/common/debug.cpp | 104 -- services/flashd/common/debug.h | 28 - services/flashd/common/define.h | 98 -- services/flashd/common/define_plus.h | 340 ----- services/flashd/common/file.cpp | 195 --- services/flashd/common/file_descriptor.cpp | 166 --- services/flashd/common/file_descriptor.h | 58 - .../flashd/common/{file.h => flash_define.h} | 39 +- services/flashd/common/forward.cpp | 789 ---------- services/flashd/common/forward.h | 107 -- services/flashd/common/serial_struct.h | 88 -- services/flashd/common/serial_struct_define.h | 1314 ----------------- services/flashd/common/session.cpp | 1062 ------------- services/flashd/common/session.h | 183 --- services/flashd/common/task.cpp | 99 -- services/flashd/common/task.h | 57 - services/flashd/common/tcp.cpp | 98 -- services/flashd/common/tcp.h | 43 - services/flashd/common/transfer.cpp | 417 ------ services/flashd/common/transfer.h | 114 -- services/flashd/common/usb.cpp | 144 -- services/flashd/common/usb.h | 41 - services/flashd/daemon/daemon.cpp | 72 +- services/flashd/daemon/daemon.h | 47 - services/flashd/daemon/daemon_app.cpp | 151 -- services/flashd/daemon/daemon_app.h | 38 - services/flashd/daemon/daemon_common.h | 41 - services/flashd/daemon/daemon_forward.cpp | 82 - services/flashd/daemon/daemon_forward.h | 31 - services/flashd/daemon/daemon_tcp.cpp | 151 -- services/flashd/daemon/daemon_tcp.h | 40 - services/flashd/daemon/daemon_unity.h | 48 - services/flashd/daemon/daemon_updater.cpp | 2 + services/flashd/daemon/daemon_usb.cpp | 498 ------- services/flashd/daemon/daemon_usb.h | 62 - services/flashd/daemon/flashd_main.cpp | 1 + services/flashd/daemon/jdwp.cpp | 279 ---- services/flashd/daemon/jdwp.h | 59 - services/flashd/daemon/main.cpp | 197 --- services/flashd/daemon/shell.cpp | 217 --- services/flashd/daemon/shell.h | 47 - services/flashd/daemon/usb_ffs.h | 218 --- services/flashd/host/client.cpp | 53 +- services/flashd/host/client.h | 59 - services/flashd/host/host_app.cpp | 177 --- services/flashd/host/host_app.h | 34 - services/flashd/host/host_common.h | 37 - services/flashd/host/host_forward.cpp | 26 - services/flashd/host/host_forward.h | 29 - services/flashd/host/host_tcp.cpp | 166 --- services/flashd/host/host_tcp.h | 38 - services/flashd/host/host_unity.cpp | 155 -- services/flashd/host/host_unity.h | 51 - services/flashd/host/host_updater.cpp | 18 +- services/flashd/host/host_updater.h | 6 +- services/flashd/host/host_usb.cpp | 550 ------- services/flashd/host/host_usb.h | 66 - services/flashd/host/main.cpp | 1 + services/flashd/host/server.cpp | 5 +- services/flashd/host/server.h | 64 - services/flashd/host/server_for_client.cpp | 2 + services/flashd/host/server_for_client.h | 60 - services/flashd/host/translate.cpp | 1 + services/flashd/host/translate.h | 31 - test/unittest/BUILD.gn | 3 + .../flashd_test/flash_host_unittest.cpp | 10 +- .../flashd_test/flash_service_unittest.cpp | 5 +- 76 files changed, 143 insertions(+), 10972 deletions(-) delete mode 100755 services/flashd/common/async_cmd.cpp delete mode 100755 services/flashd/common/async_cmd.h delete mode 100755 services/flashd/common/auth.cpp delete mode 100755 services/flashd/common/auth.h delete mode 100755 services/flashd/common/base.h delete mode 100755 services/flashd/common/channel.cpp delete mode 100755 services/flashd/common/channel.h delete mode 100755 services/flashd/common/common.h delete mode 100755 services/flashd/common/debug.cpp delete mode 100755 services/flashd/common/debug.h delete mode 100755 services/flashd/common/define.h delete mode 100755 services/flashd/common/define_plus.h delete mode 100755 services/flashd/common/file.cpp delete mode 100755 services/flashd/common/file_descriptor.cpp delete mode 100755 services/flashd/common/file_descriptor.h rename services/flashd/common/{file.h => flash_define.h} (43%) delete mode 100755 services/flashd/common/forward.cpp delete mode 100755 services/flashd/common/forward.h delete mode 100755 services/flashd/common/serial_struct.h delete mode 100755 services/flashd/common/serial_struct_define.h delete mode 100755 services/flashd/common/session.cpp delete mode 100755 services/flashd/common/session.h delete mode 100755 services/flashd/common/task.cpp delete mode 100755 services/flashd/common/task.h delete mode 100755 services/flashd/common/tcp.cpp delete mode 100755 services/flashd/common/tcp.h delete mode 100755 services/flashd/common/transfer.cpp delete mode 100755 services/flashd/common/transfer.h delete mode 100755 services/flashd/common/usb.cpp delete mode 100755 services/flashd/common/usb.h delete mode 100755 services/flashd/daemon/daemon.h delete mode 100755 services/flashd/daemon/daemon_app.cpp delete mode 100755 services/flashd/daemon/daemon_app.h delete mode 100755 services/flashd/daemon/daemon_common.h delete mode 100755 services/flashd/daemon/daemon_forward.cpp delete mode 100755 services/flashd/daemon/daemon_forward.h delete mode 100755 services/flashd/daemon/daemon_tcp.cpp delete mode 100755 services/flashd/daemon/daemon_tcp.h delete mode 100755 services/flashd/daemon/daemon_unity.h delete mode 100755 services/flashd/daemon/daemon_usb.cpp delete mode 100755 services/flashd/daemon/daemon_usb.h delete mode 100755 services/flashd/daemon/jdwp.cpp delete mode 100755 services/flashd/daemon/jdwp.h delete mode 100755 services/flashd/daemon/main.cpp delete mode 100755 services/flashd/daemon/shell.cpp delete mode 100755 services/flashd/daemon/shell.h delete mode 100755 services/flashd/daemon/usb_ffs.h delete mode 100755 services/flashd/host/client.h delete mode 100755 services/flashd/host/host_app.cpp delete mode 100755 services/flashd/host/host_app.h delete mode 100755 services/flashd/host/host_common.h delete mode 100755 services/flashd/host/host_forward.cpp delete mode 100755 services/flashd/host/host_forward.h delete mode 100755 services/flashd/host/host_tcp.cpp delete mode 100755 services/flashd/host/host_tcp.h delete mode 100755 services/flashd/host/host_unity.cpp delete mode 100755 services/flashd/host/host_unity.h delete mode 100755 services/flashd/host/host_usb.cpp delete mode 100755 services/flashd/host/host_usb.h delete mode 100755 services/flashd/host/server.h delete mode 100755 services/flashd/host/server_for_client.h delete mode 100755 services/flashd/host/translate.h diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn index 3933ab11..7a30a9fb 100755 --- a/services/flashd/BUILD.gn +++ b/services/flashd/BUILD.gn @@ -13,39 +13,40 @@ import("//build/ohos.gni") -FLASHD_HDC_PATH = "//base/update/updater/services/flashd" +FLASHD_PATH = "//base/update/updater/services/flashd" +HDC_PATH = "//developtools/hdc_standard/src" common_sources = [ - "${FLASHD_HDC_PATH}/common/async_cmd.cpp", - "${FLASHD_HDC_PATH}/common/auth.cpp", - "${FLASHD_HDC_PATH}/common/base.cpp", - "${FLASHD_HDC_PATH}/common/channel.cpp", - "${FLASHD_HDC_PATH}/common/debug.cpp", - "${FLASHD_HDC_PATH}/common/file.cpp", - "${FLASHD_HDC_PATH}/common/file_descriptor.cpp", - "${FLASHD_HDC_PATH}/common/forward.cpp", - "${FLASHD_HDC_PATH}/common/session.cpp", - "${FLASHD_HDC_PATH}/common/task.cpp", - "${FLASHD_HDC_PATH}/common/tcp.cpp", - "${FLASHD_HDC_PATH}/common/transfer.cpp", - "${FLASHD_HDC_PATH}/common/usb.cpp", + "${FLASHD_PATH}/common/base.cpp", + "${HDC_PATH}/common/async_cmd.cpp", + "${HDC_PATH}/common/auth.cpp", + "${HDC_PATH}/common/channel.cpp", + "${HDC_PATH}/common/debug.cpp", + "${HDC_PATH}/common/file.cpp", + "${HDC_PATH}/common/file_descriptor.cpp", + "${HDC_PATH}/common/forward.cpp", + "${HDC_PATH}/common/session.cpp", + "${HDC_PATH}/common/task.cpp", + "${HDC_PATH}/common/tcp.cpp", + "${HDC_PATH}/common/transfer.cpp", + "${HDC_PATH}/common/usb.cpp", ] config("flashd_hdc_config") { - include_dirs = [ "${FLASHD_HDC_PATH}/common" ] + include_dirs = [ "${FLASHD_PATH}/common" ] cflags_cc = [ "-std=c++17" ] } ohos_source_set("flashd_deamon") { sources = [ - "${FLASHD_HDC_PATH}/daemon/daemon.cpp", - "${FLASHD_HDC_PATH}/daemon/daemon_app.cpp", - "${FLASHD_HDC_PATH}/daemon/daemon_forward.cpp", - "${FLASHD_HDC_PATH}/daemon/daemon_tcp.cpp", - "${FLASHD_HDC_PATH}/daemon/daemon_unity.cpp", - "${FLASHD_HDC_PATH}/daemon/daemon_usb.cpp", - "${FLASHD_HDC_PATH}/daemon/jdwp.cpp", - "${FLASHD_HDC_PATH}/daemon/shell.cpp", + "${FLASHD_PATH}/daemon/daemon.cpp", + "${FLASHD_PATH}/daemon/daemon_unity.cpp", + "${HDC_PATH}/daemon/daemon_app.cpp", + "${HDC_PATH}/daemon/daemon_forward.cpp", + "${HDC_PATH}/daemon/daemon_tcp.cpp", + "${HDC_PATH}/daemon/daemon_usb.cpp", + "${HDC_PATH}/daemon/jdwp.cpp", + "${HDC_PATH}/daemon/shell.cpp", ] sources += common_sources @@ -72,7 +73,8 @@ ohos_source_set("flashd_deamon") { } include_dirs = [ - "${FLASHD_HDC_PATH}/daemon", + "${HDC_PATH}/daemon", + "${HDC_PATH}/common", "//base/update/updater/services/flashd", "//base/update/updater/services/flashd/daemon", "//base/update/updater/services/flashd/common", @@ -128,11 +130,12 @@ ohos_static_library("libflashd") { ] include_dirs = [ - "${FLASHD_HDC_PATH}/daemon", - "${FLASHD_HDC_PATH}/common", + "${HDC_PATH}/daemon", + "${HDC_PATH}/common", "//base/update/updater/services", "//base/update/updater/services/flashd", "//base/update/updater/services/flashd/daemon", + "//base/update/updater/services/flashd/common", "//base/update/updater/interfaces/kits/include", "//base/update/updater/services/include/package", "//base/update/updater/services/include/script", @@ -167,17 +170,17 @@ ohos_executable("ohflash") { "-Wno-unused-variable", ] sources = [ - "${FLASHD_HDC_PATH}/host/client.cpp", - "${FLASHD_HDC_PATH}/host/host_app.cpp", - "${FLASHD_HDC_PATH}/host/host_forward.cpp", - "${FLASHD_HDC_PATH}/host/host_tcp.cpp", - "${FLASHD_HDC_PATH}/host/host_unity.cpp", - "${FLASHD_HDC_PATH}/host/host_updater.cpp", - "${FLASHD_HDC_PATH}/host/host_usb.cpp", - "${FLASHD_HDC_PATH}/host/main.cpp", - "${FLASHD_HDC_PATH}/host/server.cpp", - "${FLASHD_HDC_PATH}/host/server_for_client.cpp", - "${FLASHD_HDC_PATH}/host/translate.cpp", + "${FLASHD_PATH}/host/client.cpp", + "${FLASHD_PATH}/host/host_updater.cpp", + "${FLASHD_PATH}/host/main.cpp", + "${FLASHD_PATH}/host/server.cpp", + "${FLASHD_PATH}/host/server_for_client.cpp", + "${FLASHD_PATH}/host/translate.cpp", + "${HDC_PATH}/host/host_app.cpp", + "${HDC_PATH}/host/host_forward.cpp", + "${HDC_PATH}/host/host_tcp.cpp", + "${HDC_PATH}/host/host_unity.cpp", + "${HDC_PATH}/host/host_usb.cpp", ] sources += common_sources @@ -192,7 +195,10 @@ ohos_executable("ohflash") { deps += [ "//third_party/libusb:libusb" ] include_dirs = [ - "${FLASHD_HDC_PATH}/host", + "${FLASHD_PATH}/host", + "${HDC_PATH}/host", + "${FLASHD_PATH}/common", + "${HDC_PATH}/common", "//utils/native/base/include", "//third_party/lz4/lib", "//third_party/openssl/include", @@ -229,19 +235,11 @@ group("flashhost_target_standard_mingw") { group("flashhost_target_standard_all") { deps = [ - ":flashhost_target_standard", ":flashhost_target_standard_linux", ":flashhost_target_standard_mingw", ] } -group("flashhost_target_standard_windows") { - deps = [ - ":flashhost_target_standard", - ":flashhost_target_standard_mingw", - ] -} - group("updater_flashd") { deps = [ ":libflashd" ] } diff --git a/services/flashd/common/async_cmd.cpp b/services/flashd/common/async_cmd.cpp deleted file mode 100755 index 43d5f1a9..00000000 --- a/services/flashd/common/async_cmd.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "async_cmd.h" -#define PIPE_READ 0 -#define PIPE_WRITE 1 - -namespace Hdc { -// Do not add thread-specific init op in the following methods as it's running in child thread. -AsyncCmd::AsyncCmd() -{ - Base::ZeroStruct(stdinPipe); - Base::ZeroStruct(stdoutPipe); - Base::ZeroStruct(stderrPipe); - Base::ZeroStruct(proc); - Base::ZeroStruct(procOptions); - running = false; - loop = nullptr; -} - -AsyncCmd::~AsyncCmd() -{ - WRITE_LOG(LOG_DEBUG, "~AsyncCmd"); -}; - -bool AsyncCmd::ReadyForRelease() const -{ - return !running; -} - -// manual stop will not trigger ExitCallback, we call it -void AsyncCmd::DoRelease() -{ - if (hasStop || !running) { - return; - } - hasStop = true; // must set here to deny repeate release - uv_process_kill(&proc, SIGKILL); - WRITE_LOG(LOG_DEBUG, "AsyncCmd::DoRelease finish"); -} - -void AsyncCmd::ChildReadCallback(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) -{ - AsyncCmd *thisClass = (AsyncCmd *)stream->data; - if (nread <= 0) { // stdout and stderr - WRITE_LOG(LOG_DEBUG, "Read ShellChildProcess failed %s", uv_err_name(nread)); - } else { - if (thisClass->options & OPTION_READBACK_OUT) { - thisClass->cmdResult = buf->base; - if (!thisClass->resultCallback(false, 0, thisClass->cmdResult)) { - uv_process_kill(&thisClass->proc, SIGKILL); - uv_read_stop(stream); - } - thisClass->cmdResult = STRING_EMPTY; - } else { // output all when finish - thisClass->cmdResult += buf->base; - } - } - delete[] buf->base; -} - -void AsyncCmd::ExitCallback(uv_process_t *req, int64_t exitStatus, int tersignal) -{ - auto funcReqClose = [](uv_handle_t *handle) -> void { - AsyncCmd *thisClass = (AsyncCmd *)handle->data; - if (--thisClass->uvRef == 0) { - thisClass->running = false; - } - }; - AsyncCmd *thisClass = (AsyncCmd *)req->data; - thisClass->hasStop = true; // callback maybe call dorelease, so deny repeate ExitCallback - - thisClass->resultCallback(true, exitStatus, thisClass->cmdResult); - WRITE_LOG(LOG_DEBUG, "AsyncCmd::ExitCallback"); - thisClass->uvRef = 4; - Base::TryCloseHandle((uv_handle_t *)&thisClass->stdinPipe, true, funcReqClose); - Base::TryCloseHandle((uv_handle_t *)&thisClass->stdoutPipe, true, funcReqClose); - Base::TryCloseHandle((uv_handle_t *)&thisClass->stderrPipe, true, funcReqClose); - Base::TryCloseHandle((uv_handle_t *)req, true, funcReqClose); - thisClass->cmdResult = STRING_EMPTY; -} - -bool AsyncCmd::Initial(uv_loop_t *loopIn, const CmdResultCallback callback, uint32_t optionsIn) -{ - if (running) { - return false; - } - loop = loopIn; - resultCallback = callback; - options = optionsIn; - return true; -} - -bool AsyncCmd::ExecuteCommand(const string &command) -{ - string cmd = command; - Base::Trim(cmd, "\""); - if (!(options & OPTION_COMMAND_ONETIME)) { - if (StartProcess() < 0) { - return false; - } - if (options & OPTION_APPEND_NEWLINE) { - cmd += "\n"; - } - Base::SendToStream((uv_stream_t *)&stdinPipe, (uint8_t *)cmd.c_str(), cmd.size() + 1); - } else { - if (StartProcess(cmd) < 0) { - return false; - } - } - return true; -} - -int AsyncCmd::StartProcess(string command) -{ - constexpr auto countStdIOCount = 3; - char **ppShellArgs = nullptr; - string shellPath = Base::GetShellPath(); - uv_stdio_container_t stdioShellProc[countStdIOCount]; - while (true) { - uv_pipe_init(loop, &stdinPipe, 1); - uv_pipe_init(loop, &stdoutPipe, 1); - uv_pipe_init(loop, &stderrPipe, 1); - stdinPipe.data = this; - stdoutPipe.data = this; - stderrPipe.data = this; - procOptions.stdio = stdioShellProc; - procOptions.stdio[STDIN_FILENO].flags = (uv_stdio_flags)(UV_CREATE_PIPE | UV_READABLE_PIPE); - procOptions.stdio[STDIN_FILENO].data.stream = (uv_stream_t *)&stdinPipe; - procOptions.stdio[STDOUT_FILENO].flags = (uv_stdio_flags)(UV_CREATE_PIPE | UV_WRITABLE_PIPE); - procOptions.stdio[STDOUT_FILENO].data.stream = (uv_stream_t *)&stdoutPipe; - procOptions.stdio[STDERR_FILENO].flags = (uv_stdio_flags)(UV_CREATE_PIPE | UV_WRITABLE_PIPE); - procOptions.stdio[STDERR_FILENO].data.stream = (uv_stream_t *)&stderrPipe; - procOptions.stdio_count = countStdIOCount; - procOptions.file = shellPath.c_str(); - procOptions.exit_cb = ExitCallback; - - if (command.size() > 0) { - constexpr auto args = 4; - ppShellArgs = new char *[args]; - const string shellCommandFlag = "-c"; - ppShellArgs[0] = (char *)shellPath.c_str(); - ppShellArgs[1] = (char *)shellCommandFlag.c_str(); - ppShellArgs[args - CMD_ARG1_COUNT] = (char *)command.c_str(); - ppShellArgs[args - 1] = nullptr; - } else { - ppShellArgs = new char *[CMD_ARG1_COUNT]; - ppShellArgs[0] = (char *)shellPath.c_str(); - ppShellArgs[1] = nullptr; - } - procOptions.args = ppShellArgs; - proc.data = this; - - if (uv_spawn(loop, &proc, &procOptions)) { - WRITE_LOG(LOG_FATAL, "Spawn shell process failed"); - break; - } - if (uv_read_start((uv_stream_t *)&stdoutPipe, Base::AllocBufferCallback, ChildReadCallback)) { - break; - } - if (uv_read_start((uv_stream_t *)&stderrPipe, Base::AllocBufferCallback, ChildReadCallback)) { - break; - } - running = true; - break; - } - if (ppShellArgs) { - delete[] ppShellArgs; - } - if (!running) { - // failed - resultCallback(true, -1, "Start process failed"); - return -1; - } else { - return 0; - } -} -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/async_cmd.h b/services/flashd/common/async_cmd.h deleted file mode 100755 index f7772282..00000000 --- a/services/flashd/common/async_cmd.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_ASYNC_CMD_H -#define HDC_ASYNC_CMD_H -#include "common.h" - -namespace Hdc { -class AsyncCmd { -public: - AsyncCmd(); - virtual ~AsyncCmd(); - enum AsyncCmdOption { - OPTION_APPEND_NEWLINE = 1, - OPTION_COMMAND_ONETIME = 2, - OPTION_READBACK_OUT = 4, - USB_OPTION_RESERVE8 = 8, - }; - // 1)is finish 2)exitStatus 3)resultString(maybe empty) - using CmdResultCallback = std::function; - static uint32_t GetDefaultOption() - { - return OPTION_APPEND_NEWLINE | OPTION_COMMAND_ONETIME; - } - // uv_loop_t loop is given to uv_spawn, which can't be const - bool Initial(uv_loop_t *loopIn, const CmdResultCallback callback, uint32_t optionsIn = GetDefaultOption()); - void DoRelease(); // Release process resources - bool ExecuteCommand(const string &command); - bool ReadyForRelease() const; - -private: - int StartProcess(string command = STRING_EMPTY); - // uv_read_cb callback 1st parameter can't be changed, const can't be added - static void ChildReadCallback(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); - // uv_exit_cb callback 1st parameter can't be changed, const can't be added - static void ExitCallback(uv_process_t *req, int64_t exitStatus, int tersignal); - - uv_loop_t *loop; - // loop is given to uv_spawn, which can't be const - uv_pipe_t stdinPipe; - uv_pipe_t stdoutPipe; - uv_pipe_t stderrPipe; - uv_process_t proc; - uv_process_options_t procOptions; - CmdResultCallback resultCallback; - string cmdResult; - bool running; - bool hasStop = false; - uint32_t options = 0; - uint8_t uvRef = 0; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/common/auth.cpp b/services/flashd/common/auth.cpp deleted file mode 100755 index 50f148b4..00000000 --- a/services/flashd/common/auth.cpp +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "auth.h" -#include -#include -#include -#include -#include - -using namespace Hdc; -#define BIGNUMTOBIT 32 - -namespace HdcAuth { -// ---------------------------------------Cheat compiler--------------------------------------------------------- -#ifdef HDC_HOST - -bool AuthVerify(uint8_t *token, uint8_t *sig, int siglen) -{ - return false; -}; -bool PostUIConfirm(string publicKey) -{ - return false; -} - -#else // daemon - -bool GenerateKey(const char *file) -{ - return false; -}; -int AuthSign(void *rsa, const unsigned char *token, size_t tokenSize, void *sig) -{ - return 0; -}; -int GetPublicKeyFileBuf(unsigned char *data, size_t len) -{ - return 0; -} - -#endif -// ------------------------------------------------------------------------------------------------ - -const uint32_t RSANUMBYTES = 256; // 2048 bit key length -const uint32_t RSANUMWORDS = (RSANUMBYTES / sizeof(uint32_t)); -struct RSAPublicKey { - int wordModulusSize; // Length of n[] in number of uint32_t */ - uint32_t rsaN0inv; // -1 / n[0] mod 2^32 - uint32_t modulus[RSANUMWORDS]; // modulus as little endian array - uint32_t rr[RSANUMWORDS]; // R^2 as little endian array - int exponent; // 3 or 65537 -}; - -#ifdef HDC_HOST -// Convert OpenSSL RSA private key to pre-computed RSAPublicKey format -int RSA2RSAPublicKey(RSA *rsa, RSAPublicKey *publicKey) -{ - int result = 1; - unsigned int i; - BN_CTX *ctx = BN_CTX_new(); - BIGNUM *r32 = BN_new(); - BIGNUM *rsaRR = BN_new(); - BIGNUM *rsaR = BN_new(); - BIGNUM *rsaRem = BN_new(); - BIGNUM *rsaN0inv = BN_new(); -#ifdef OPENSSL_IS_BORINGSSL - // boringssl - BIGNUM *n = BN_new(); - BN_copy(n, rsa->n); - publicKey->exponent = BN_get_word(rsa->e); -#else - // openssl -#if OPENSSL_VERSION_NUMBER >= 0x10100005L - BIGNUM *n = (BIGNUM *)RSA_get0_n(rsa); - publicKey->exponent = BN_get_word(RSA_get0_e(rsa)); -#else - BIGNUM *n = BN_new(); - BN_copy(n, rsa->n); - publicKey->exponent = BN_get_word(rsa->e); -#endif - -#endif // OPENSSL_IS_BORINGSSL - while (true) { - if (RSA_size(rsa) != RSANUMBYTES) { - result = 0; - break; - } - - BN_set_bit(r32, BIGNUMTOBIT); - BN_set_bit(rsaR, RSANUMWORDS * BIGNUMTOBIT); - BN_mod_sqr(rsaRR, rsaR, n, ctx); - BN_div(nullptr, rsaRem, n, r32, ctx); - BN_mod_inverse(rsaN0inv, rsaRem, r32, ctx); - publicKey->wordModulusSize = RSANUMWORDS; - publicKey->rsaN0inv = 0 - BN_get_word(rsaN0inv); - for (i = 0; i < RSANUMWORDS; ++i) { - BN_div(rsaRR, rsaRem, rsaRR, r32, ctx); - publicKey->rr[i] = BN_get_word(rsaRem); - BN_div(n, rsaRem, n, r32, ctx); - publicKey->modulus[i] = BN_get_word(rsaRem); - } - break; - } - - BN_free(rsaR); - BN_free(rsaRR); - BN_free(n); - BN_free(r32); - BN_free(rsaN0inv); - BN_free(rsaRem); - BN_CTX_free(ctx); - return result; -} - -int GetUserInfo(char *buf, size_t len) -{ - char hostname[BUF_SIZE_DEFAULT]; - char username[BUF_SIZE_DEFAULT]; - uv_passwd_t pwd; - int ret = -1; - size_t bufSize = sizeof(hostname); - if (uv_os_gethostname(hostname, &bufSize) < 0 && EOK != strcpy_s(hostname, sizeof(hostname), "unknown")) { - return ERR_API_FAIL; - } - if (!uv_os_get_passwd(&pwd) && !strcpy_s(username, sizeof(username), pwd.username)) { - ret = 0; - } - uv_os_free_passwd(&pwd); - if (ret < 0 && EOK != strcpy_s(username, sizeof(username), "unknown")) { - return ERR_API_FAIL; - } - if (snprintf_s(buf, len, len - 1, " %s@%s", username, hostname) < 0) { - return ERR_BUF_OVERFLOW; - } - return RET_SUCCESS; -} - -int WritePublicKeyfile(RSA *private_key, const char *private_key_path) -{ - RSAPublicKey publicKey; - char info[BUF_SIZE_DEFAULT]; - int ret = 0; - string path = private_key_path + string(".pub"); - - ret = RSA2RSAPublicKey(private_key, &publicKey); - if (!ret) { - WRITE_LOG(LOG_DEBUG, "Failed to convert to publickey\n"); - return 0; - } - vector vec = Base::Base64Encode((const uint8_t *)&publicKey, sizeof(RSAPublicKey)); - if (!vec.size()) { - return 0; - } - GetUserInfo(info, sizeof(info)); - vec.insert(vec.end(), (uint8_t *)info, (uint8_t *)info + strlen(info)); - ret = Base::WriteBinFile(path.c_str(), vec.data(), vec.size(), true); - return ret >= 0 ? 1 : 0; -} - -bool GenerateKey(const char *file) -{ - EVP_PKEY *publicKey = EVP_PKEY_new(); - BIGNUM *exponent = BN_new(); - RSA *rsa = RSA_new(); - mode_t old_mask; - FILE *fKey = nullptr; - bool ret = false; - - while (true) { - WRITE_LOG(LOG_DEBUG, "generate_key '%s'\n", file); - if (!publicKey || !exponent || !rsa) { - WRITE_LOG(LOG_DEBUG, "Failed to allocate key"); - break; - } - - BN_set_word(exponent, RSA_F4); - RSA_generate_key_ex(rsa, 2048, exponent, nullptr); - EVP_PKEY_set1_RSA(publicKey, rsa); - old_mask = umask(077); // 077:permission - - fKey = fopen(file, "w"); - if (!fKey) { - WRITE_LOG(LOG_DEBUG, "Failed to open '%s'\n", file); - umask(old_mask); - break; - } - umask(old_mask); - if (!PEM_write_PrivateKey(fKey, publicKey, nullptr, nullptr, 0, nullptr, nullptr)) { - WRITE_LOG(LOG_DEBUG, "Failed to write key"); - break; - } - if (!WritePublicKeyfile(rsa, file)) { - WRITE_LOG(LOG_DEBUG, "Failed to write public key"); - break; - } - ret = true; - break; - } - - RSA_free(rsa); - EVP_PKEY_free(publicKey); - BN_free(exponent); - if (fKey) - fclose(fKey); - return ret; -} - -bool ReadKey(const char *file, list *listPrivateKey) -{ - FILE *f = nullptr; - bool ret = false; - - while (true) { - if (!(f = fopen(file, "r"))) { - break; - } - RSA *rsa = RSA_new(); - if (!PEM_read_RSAPrivateKey(f, &rsa, nullptr, nullptr)) { - RSA_free(rsa); - break; - } - listPrivateKey->push_back((void *)rsa); - ret = true; - break; - } - if (f) { - fclose(f); - } - return ret; -} - -int GetUserKeyPath(string &path) -{ - struct stat status; - const char harmoneyPath[] = ".harmony"; - const char hdcKeyFile[] = "hdckey"; - char buf[BUF_SIZE_DEFAULT]; - size_t len = BUF_SIZE_DEFAULT; - // $home - if (uv_os_homedir(buf, &len) < 0) - return false; - path = string(buf) + Base::GetPathSep() + string(harmoneyPath) + Base::GetPathSep(); - if (stat(path.c_str(), &status)) { - uv_fs_t req; - uv_fs_mkdir(nullptr, &req, path.c_str(), 0750, nullptr); // 0750:permission - uv_fs_req_cleanup(&req); - if (req.result < 0) { - WRITE_LOG(LOG_DEBUG, "Cannot mkdir '%s'", path.c_str()); - return false; - } - } - path += hdcKeyFile; - return true; -} - -bool LoadHostUserKey(list *listPrivateKey) -{ - struct stat status; - string path; - if (!GetUserKeyPath(path)) { - return false; - } - if (stat(path.c_str(), &status) == -1) { - if (!GenerateKey(path.c_str())) { - WRITE_LOG(LOG_DEBUG, "Failed to generate new key"); - return false; - } - } - if (!ReadKey(path.c_str(), listPrivateKey)) { - return false; - } - return true; -} - -int AuthSign(void *rsa, const unsigned char *token, size_t tokenSize, void *sig) -{ - unsigned int len; - if (!RSA_sign(NID_sha1, token, tokenSize, (unsigned char *)sig, &len, (RSA *)rsa)) { - return 0; - } - return (int)len; -} - -int GetPublicKeyFileBuf(unsigned char *data, size_t len) -{ - string path; - int ret; - - if (!GetUserKeyPath(path)) { - return 0; - } - path += ".pub"; - ret = Base::ReadBinFile(path.c_str(), (void **)data, len); - if (ret <= 0) { - return 0; - } - data[ret] = '\0'; - return ret + 1; -} - -#else // daemon - -bool RSAPublicKey2RSA(const uint8_t *keyBuf, RSA **key) -{ - const int pubKeyModulusSize = 256; - const int pubKeyModulusSizeWords = pubKeyModulusSize / 4; - - const RSAPublicKey *keyStruct = reinterpret_cast(keyBuf); - bool ret = false; - uint8_t modulusBuffer[pubKeyModulusSize]; - RSA *newKey = RSA_new(); - if (!newKey) { - goto cleanup; - } - if (keyStruct->wordModulusSize != pubKeyModulusSizeWords) { - goto cleanup; - } - if (memcpy_s(modulusBuffer, sizeof(modulusBuffer), keyStruct->modulus, sizeof(modulusBuffer)) != EOK) { - goto cleanup; - } - Base::ReverseBytes(modulusBuffer, sizeof(modulusBuffer)); - -#ifdef OPENSSL_IS_BORINGSSL - // boringssl - newKey->n = BN_bin2bn(modulusBuffer, sizeof(modulusBuffer), nullptr); - newKey->e = BN_new(); - if (!newKey->e || !BN_set_word(newKey->e, keyStruct->exponent) || !newKey->n) { - goto cleanup; - } -#else - // openssl -#if OPENSSL_VERSION_NUMBER >= 0x10100005L - RSA_set0_key(newKey, BN_bin2bn(modulusBuffer, sizeof(modulusBuffer), nullptr), BN_new(), BN_new()); -#else - newKey->n = BN_bin2bn(modulusBuffer, sizeof(modulusBuffer), nullptr); - newKey->e = BN_new(); - if (!newKey->e || !BN_set_word(newKey->e, keyStruct->exponent) || !newKey->n) { - goto cleanup; - } -#endif -#endif - - *key = newKey; - ret = true; - -cleanup: - if (!ret && newKey) { - RSA_free(newKey); - } - return ret; -} - -void ReadDaemonKeys(const char *file, list *listPublicKey) -{ - char buf[BUF_SIZE_DEFAULT2]; - char *sep = nullptr; - int ret; - FILE *f = fopen(file, "re"); - if (!f) { - WRITE_LOG(LOG_DEBUG, "Can't open '%s'", file); - return; - } - while (fgets(buf, sizeof(buf), f)) { - RSAPublicKey *key = new RSAPublicKey(); - if (!key) { - break; - } - sep = strpbrk(buf, " \t"); - if (sep) { - *sep = '\0'; - } - ret = Base::Base64DecodeBuf(reinterpret_cast(buf), strlen(buf), (uint8_t *)key); - if (ret != sizeof(RSAPublicKey)) { - WRITE_LOG(LOG_DEBUG, "%s: Invalid base64 data ret=%d", file, ret); - delete key; - continue; - } - - if (key->wordModulusSize != RSANUMWORDS) { - WRITE_LOG(LOG_DEBUG, "%s: Invalid key len %d\n", file, key->wordModulusSize); - delete key; - continue; - } - listPublicKey->push_back(key); - } - fclose(f); -} - -bool AuthVerify(uint8_t *token, uint8_t *sig, int siglen) -{ - list listPublicKey; - uint8_t authKeyIndex = 0; - void *ptr = nullptr; - int ret = 0; - int childRet = 0; - while (KeylistIncrement(&listPublicKey, authKeyIndex, &ptr)) { - RSA *rsa = nullptr; - if (!RSAPublicKey2RSA((const uint8_t *)ptr, &rsa)) { - break; - } - childRet = RSA_verify(NID_sha1, (const unsigned char *)token, RSA_TOKEN_SIZE, (const unsigned char *)sig, - siglen, rsa); - RSA_free(rsa); - if (childRet) { - ret = 1; - break; - } - } - FreeKey(true, &listPublicKey); - return ret; -} - -void LoadDaemonKey(list *listPublicKey) -{ -#ifdef HDC_PCDEBUG - char keyPaths[][BUF_SIZE_SMALL] = { "/root/.harmony/hdckey.pub" }; -#else - char keyPaths[][BUF_SIZE_SMALL] = { "/hdc_keys", "/data/misc/hdc/hdc_keys" }; -#endif - int num = sizeof(keyPaths) / sizeof(keyPaths[0]); - struct stat buf; - - for (int i = 0; i < num; ++i) { - char *p = keyPaths[i]; - if (!stat(p, &buf)) { - WRITE_LOG(LOG_DEBUG, "Loading keys from '%s'", p); - ReadDaemonKeys(p, listPublicKey); - } - } -} - -bool PostUIConfirm(string publicKey) -{ - // Because the Hi3516 development board has no UI support for the time being, all public keys are received and - // By default, the system UI will record the public key /data/misc/hdc/hdckey/data/misc/hdc/hdckey - return true; -} -#endif // HDC_HOST - -// --------------------------------------common code------------------------------------------ -bool KeylistIncrement(list *listKey, uint8_t &authKeyIndex, void **out) -{ - if (!listKey->size()) { -#ifdef HDC_HOST - LoadHostUserKey(listKey); -#else - LoadDaemonKey(listKey); -#endif - } - if (authKeyIndex == listKey->size()) { - // all finish - return false; - } - auto listIndex = listKey->begin(); - std::advance(listIndex, ++authKeyIndex); - *out = *listIndex; - if (!*out) { - return false; - } - return true; -} - -void FreeKey(bool publicOrPrivate, list *listKey) -{ - for (auto &&v : *listKey) { - if (publicOrPrivate) { - delete (RSAPublicKey *)v; - v = nullptr; - } else { - RSA_free((RSA *)v); - v = nullptr; - } - } - listKey->clear(); -} -} diff --git a/services/flashd/common/auth.h b/services/flashd/common/auth.h deleted file mode 100755 index 1e2083b6..00000000 --- a/services/flashd/common/auth.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_AUTH_H -#define HDC_AUTH_H -#include "common.h" - -// If these functions occupy too high a load, you can consider placing them in a thread for execution, and perform -// subsequent processing in the callback directly after completion. -namespace HdcAuth { -const uint8_t RSA_TOKEN_SIZE = 20; // SHA_DIGEST_LENGTH -// in host out==RSA*, in daemon out=RSAPublicKey* -bool KeylistIncrement(list *listKey, uint8_t &authKeyIndex, void **out); -void FreeKey(bool publicOrPrivate, list *listKey); - -// host -bool GenerateKey(const char *file); -int AuthSign(void *rsa, const unsigned char *token, size_t tokenSize, void *sig); -int GetPublicKeyFileBuf(unsigned char *data, size_t len); - -// daemon -bool AuthVerify(uint8_t *token, uint8_t *sig, int siglen); -bool PostUIConfirm(string pkey); -} - -#endif \ No newline at end of file diff --git a/services/flashd/common/base.h b/services/flashd/common/base.h deleted file mode 100755 index 9a6b12be..00000000 --- a/services/flashd/common/base.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_BASE_H -#define HDC_BASE_H -#include "common.h" - -namespace Hdc { -namespace Base { - void SetLogLevel(const uint8_t logLevel); - void PrintLogEx(const char *functionName, int line, uint8_t logLevel, const char *msg, ...); - void PrintMessage(const char *fmt, ...); - // tcpHandle can't be const as it's passed into uv_tcp_keepalive - void SetTcpOptions(uv_tcp_t *tcpHandle); - // Realloc need to update origBuf&origSize which can't be const - void ReallocBuf(uint8_t **origBuf, int *nOrigSize, const int indexUsedBuf, int sizeWanted); - // handle&sendHandle must keep sync with uv_write - int SendToStreamEx(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen, uv_stream_t *handleSend, - const void *finishCallback, const void *pWriteReqData); - int SendToStream(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen); - // As an uv_write_cb it must keep the same as prototype - void SendCallback(uv_write_t *req, int status); - // As an uv_alloc_cb it must keep the same as prototype - void AllocBufferCallback(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf); - uint64_t GetRuntimeMSec(); - string GetRandomString(const uint16_t expectedLen); - int GetRandomNum(const int min, const int max); - uint64_t GetRandom(const uint64_t min = 0, const uint64_t max = UINT64_MAX); - int ConnectKey2IPPort(const char *connectKey, char *outIP, uint16_t *outPort); - // As an uv_work_cb it must keep the same as prototype - // clang-format off - int StartWorkThread(uv_loop_t *loop, uv_work_cb pFuncWorkThread, - uv_after_work_cb pFuncAfterThread, void *pThreadData); - // clang-format on - // As an uv_work_cb it must keep the same as prototype - void FinishWorkThread(uv_work_t *req, int status); - int GetMaxBufSize(); - bool TryCloseLoop(uv_loop_t *ptrLoop, const char *callerName); - void TryCloseHandle(const uv_handle_t *handle); - void TryCloseHandle(const uv_handle_t *handle, uv_close_cb closeCallBack); - void TryCloseHandle(const uv_handle_t *handle, bool alwaysCallback, uv_close_cb closeCallBack); - char **SplitCommandToArgs(const char *cmdStringLine, int *slotIndex); - bool SetHdcProperty(const char *key, const char *value); - // value needs to save results which can't be const - bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf); - bool RunPipeComand(const char *cmdString, char *outBuf, uint16_t sizeOutBuf, bool ignoreTailLF); - // results need to save in buf which can't be const - int ReadBinFile(const char *pathName, void **buf, const int bufLen); - int WriteBinFile(const char *pathName, const uint8_t *buf, const int bufLen, bool newFile = false); - void CloseIdleCallback(uv_handle_t *handle); - void CloseTimerCallback(uv_handle_t *handle); - int ProgramMutex(const char *procname, bool checkOrNew); - // result needs to save results which can't be const - void SplitString(const string &origString, const string &seq, vector &resultStrings); - string GetShellPath(); - uint64_t HostToNet(uint64_t val); - uint64_t NetToHost(uint64_t val); - string GetFullFilePath(const string &s); - int CreateSocketPair(int *fds); - void CloseSocketPair(const int *fds); - int StringEndsWith(string s, string sub); - bool CheckDirectoryOrPath(const char *localPath, bool pathOrDir, bool readWrite); - int Base64EncodeBuf(const uint8_t *input, const int length, uint8_t *bufOut); - vector Base64Encode(const uint8_t *input, const int length); - int Base64DecodeBuf(const uint8_t *input, const int length, uint8_t *bufOut); - string Base64Decode(const uint8_t *input, const int length); - void ReverseBytes(void *start, int size); - string CanonicalizeSpecPath(string &src); - // Just zero a POD type, such as a structure or union - template int ZeroStruct(T &structBuf) - { - return memset_s(&structBuf, sizeof(T), 0, sizeof(T)); - } - // just zero a statically allocated array of POD or built-in types - template int ZeroArray(T (&arrayBuf)[N]) - { - return memset_s(arrayBuf, sizeof(T) * N, 0, sizeof(T) * N); - } - // just zero memory buf, such as pointer - template int ZeroBuf(T &arrayBuf, int size) - { - return memset_s(arrayBuf, size, 0, size); - } - // clang-format off - const string StringFormat(const char * const formater, ...); - const string StringFormat(const char * const formater, va_list &vaArgs); - // clang-format on - string GetVersion(); - bool IdleUvTask(uv_loop_t *loop, void *data, uv_idle_cb cb); - bool TimerUvTask(uv_loop_t *loop, void *data, uv_timer_cb cb, int repeatTimeout = UV_DEFAULT_INTERVAL); - bool DelayDo(uv_loop_t *loop, const int delayMs, const uint8_t flag, string msg, void *data, - std::function cb); - inline bool DelayDoSimple(uv_loop_t *loop, const int delayMs, - std::function cb) - { - return DelayDo(loop, delayMs, 0, "", nullptr, cb); - } - inline bool DoNextLoop(uv_loop_t *loop, void *data, std::function cb) - { - return DelayDo(loop, 0, 0, "", data, cb); - } - - // Trim from right side - inline string &RightTrim(string &s, const string &w = WHITE_SPACES) - { - s.erase(s.find_last_not_of(w) + 1); - return s; - } - - // Trim from left side - inline string &LeftTrim(string &s, const string &w = WHITE_SPACES) - { - s.erase(0, s.find_first_not_of(w)); - return s; - } - - // Trim from both sides - inline string &Trim(string &s, const string &w = WHITE_SPACES) - { - return LeftTrim(RightTrim(s, w), w); - } - string ReplaceAll(string str, const string from, const string to); - uint8_t CalcCheckSum(const uint8_t *data, int len); - string GetFileNameAny(string &path); - string GetCwd(); - string GetTmpDir(); - uv_os_sock_t DuplicateUvSocket(uv_tcp_t *tcp); - vector Md5Sum(uint8_t *buf, int size); - bool IsRoot(); - char GetPathSep(); - bool IsAbsolutePath(string &path); -} // namespace base -} // namespace Hdc - -#endif // HDC_BASE_H \ No newline at end of file diff --git a/services/flashd/common/channel.cpp b/services/flashd/common/channel.cpp deleted file mode 100755 index 8d944ac5..00000000 --- a/services/flashd/common/channel.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "channel.h" -namespace Hdc { -HdcChannelBase::HdcChannelBase(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn) -{ - SetChannelTCPString(addrString); - isServerOrClient = serverOrClient; - loopMain = loopMainIn; - uv_rwlock_init(&mainAsync); - uv_async_init(loopMain, &asyncMainLoop, MainAsyncCallback); - uv_rwlock_init(&lockMapChannel); -} - -HdcChannelBase::~HdcChannelBase() -{ - ClearChannels(); - // clear - if (!uv_is_closing((uv_handle_t *)&asyncMainLoop)) { - uv_close((uv_handle_t *)&asyncMainLoop, nullptr); - } - - uv_rwlock_destroy(&mainAsync); - uv_rwlock_destroy(&lockMapChannel); -} - -vector HdcChannelBase::GetChannelHandshake(string &connectKey) const -{ - vector ret; - // clang-format off - struct ChannelHandShake handshake = {{0}}; - // clang-format on - Base::ZeroStruct(handshake); - if (strcpy_s(handshake.banner, sizeof(handshake.banner), HANDSHAKE_MESSAGE.c_str()) != EOK) { - return ret; - } - if (strcpy_s(handshake.connectKey, sizeof(handshake.connectKey), connectKey.c_str()) != EOK) { - return ret; - } - ret.insert(ret.begin(), (uint8_t *)&handshake, (uint8_t *)&handshake + sizeof(ChannelHandShake)); - return ret; -} - -bool HdcChannelBase::SetChannelTCPString(const string &addrString) -{ - bool ret = false; - while (true) { - if (addrString.find(":") == string::npos) { - break; - } - string host = addrString.substr(0, addrString.find(":")); - string port = addrString.substr(addrString.find(":") + 1); - channelPort = std::atoi(port.c_str()); - sockaddr_in addr; - if (!channelPort || uv_ip4_addr(host.c_str(), channelPort, &addr) != 0) { - break; - } - channelHost = host; - channelHostPort = addrString; - ret = true; - break; - } - if (!ret) { - channelPort = 0; - channelHost = STRING_EMPTY; - channelHostPort = STRING_EMPTY; - } - return ret; -} - -void HdcChannelBase::ClearChannels() -{ - for (auto v : mapChannel) { - HChannel hChannel = (HChannel)v.second; - if (!hChannel->isDead) { - FreeChannel(hChannel->channelId); - } - } -} - -void HdcChannelBase::WorkerPendding() -{ - WRITE_LOG(LOG_DEBUG, "Begin host channel pendding"); - uv_run(loopMain, UV_RUN_DEFAULT); - uv_loop_close(loopMain); -} - -void HdcChannelBase::ReadStream(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf) -{ - int size = 0; - int indexBuf = 0; - int childRet = 0; - bool needExit = false; - HChannel hChannel = (HChannel)tcp->data; - HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; - - if (nread == UV_ENOBUFS) { - WRITE_LOG(LOG_DEBUG, "HdcChannelBase::ReadStream Pipe IOBuf max"); - return; - } else if (nread == 0) { - // maybe just afer accept, second client req - WRITE_LOG(LOG_DEBUG, "HdcChannelBase::ReadStream idle read"); - return; - } else if (nread < 0) { - Base::TryCloseHandle((uv_handle_t *)tcp); - WRITE_LOG(LOG_DEBUG, "HdcChannelBase::ReadStream failed2:%s", uv_err_name(nread)); - needExit = true; - goto Finish; - } else { - hChannel->availTailIndex += nread; - } - while (hChannel->availTailIndex > DWORD_SERIALIZE_SIZE) { - size = ntohl(*(uint32_t *)(hChannel->ioBuf + indexBuf)); // big endian - if (size <= 0 || (uint32_t)size > HDC_BUF_MAX_BYTES) { - needExit = true; - break; - } - if (hChannel->availTailIndex - DWORD_SERIALIZE_SIZE < size) { - break; - } - childRet = thisClass->ReadChannel(hChannel, (uint8_t *)hChannel->ioBuf + DWORD_SERIALIZE_SIZE + indexBuf, size); - if (childRet < 0) { - if (!hChannel->keepAlive) { - needExit = true; - break; - } - } - // update io - hChannel->availTailIndex -= (DWORD_SERIALIZE_SIZE + size); - indexBuf += DWORD_SERIALIZE_SIZE + size; - } - if (indexBuf > 0 && hChannel->availTailIndex > 0) { - if (memmove_s(hChannel->ioBuf, hChannel->bufSize, hChannel->ioBuf + indexBuf, hChannel->availTailIndex)) { - needExit = true; - goto Finish; - } - } - -Finish: - if (needExit) { - thisClass->FreeChannel(hChannel->channelId); - WRITE_LOG(LOG_DEBUG, "Read Stream needExit, FreeChannel finish"); - } -} - -void HdcChannelBase::WriteCallback(uv_write_t *req, int status) -{ - HChannel hChannel = (HChannel)req->handle->data; - --hChannel->sendRef; - HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; - if (status < 0) { - Base::TryCloseHandle((uv_handle_t *)req->handle); - if (!hChannel->isDead && !hChannel->sendRef) { - thisClass->FreeChannel(hChannel->channelId); - WRITE_LOG(LOG_DEBUG, "WriteCallback TryCloseHandle"); - } - } - delete[]((uint8_t *)req->data); - delete req; -} - -void HdcChannelBase::AsyncMainLoopTask(uv_idle_t *handle) -{ - AsyncParam *param = (AsyncParam *)handle->data; - HdcChannelBase *thisClass = (HdcChannelBase *)param->thisClass; - - switch (param->method) { - case ASYNC_FREE_SESSION: { - // alloc/release should pair in main thread. - thisClass->FreeChannel(param->sid); - break; - } - default: - break; - } - if (param->data) { - delete[]((uint8_t *)param->data); - } - delete param; - uv_close((uv_handle_t *)handle, Base::CloseIdleCallback); -} - -// multiple uv_async_send() calls may be merged by libuv,so not each call will yield callback as expected. -// eg: if uv_async_send() 5 times before callback calling,it will be called only once. -// if uv_async_send() is called again after callback calling, it will be called again. -void HdcChannelBase::MainAsyncCallback(uv_async_t *handle) -{ - HdcChannelBase *thisClass = (HdcChannelBase *)handle->data; - if (uv_is_closing((uv_handle_t *)thisClass->loopMain)) { - return; - } - list::iterator i; - list &lst = thisClass->lstMainThreadOP; - uv_rwlock_wrlock(&thisClass->mainAsync); - for (i = lst.begin(); i != lst.end();) { - AsyncParam *param = (AsyncParam *)*i; - Base::IdleUvTask(thisClass->loopMain, param, AsyncMainLoopTask); - i = lst.erase(i); - } - uv_rwlock_wrunlock(&thisClass->mainAsync); -} - -void HdcChannelBase::PushAsyncMessage(const uint32_t channelId, const uint8_t method, const void *data, - const int dataSize) -{ - if (uv_is_closing((uv_handle_t *)&asyncMainLoop)) { - return; - } - auto param = new AsyncParam(); - if (!param) { - return; - } - param->sid = channelId; // Borrow SID storage - param->thisClass = this; - param->method = method; - if (dataSize > 0) { - param->dataSize = dataSize; - param->data = new uint8_t[param->dataSize](); - if (!param->data) { - delete param; - return; - } - if (memcpy_s((uint8_t *)param->data, param->dataSize, data, dataSize)) { - delete[]((uint8_t *)param->data); - delete param; - return; - } - } - asyncMainLoop.data = this; - uv_rwlock_wrlock(&mainAsync); - lstMainThreadOP.push_back(param); - uv_rwlock_wrunlock(&mainAsync); - uv_async_send(&asyncMainLoop); -} - -// client to server, or vice versa -// works only in current working thread -void HdcChannelBase::Send(const uint32_t channelId, uint8_t *bufPtr, const int size) -{ - uv_stream_t *sendStream = nullptr; - int sizeNewBuf = size + DWORD_SERIALIZE_SIZE; - HChannel hChannel = (HChannel)AdminChannel(OP_QUERY, channelId, nullptr); - if (!hChannel || hChannel->isDead) { - return; - } - auto data = new uint8_t[sizeNewBuf](); - if (!data) { - return; - } - *(uint32_t *)data = htonl(size); // big endian - if (memcpy_s(data + DWORD_SERIALIZE_SIZE, sizeNewBuf - DWORD_SERIALIZE_SIZE, bufPtr, size)) { - delete[] data; - return; - } - if (hChannel->hWorkThread == uv_thread_self()) { - sendStream = (uv_stream_t *)&hChannel->hWorkTCP; - } else { - sendStream = (uv_stream_t *)&hChannel->hChildWorkTCP; - } - if (!uv_is_closing((const uv_handle_t *)sendStream) && uv_is_writable(sendStream)) { - ++hChannel->sendRef; - Base::SendToStreamEx(sendStream, data, sizeNewBuf, nullptr, (void *)WriteCallback, data); - } -} - -void HdcChannelBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) -{ - if (sizeWanted <= 0) { - return; - } - HChannel context = (HChannel)handle->data; - Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); - buf->base = (char *)context->ioBuf + context->availTailIndex; - buf->len = context->bufSize - context->availTailIndex - 1; - if (buf->len < 0) { - buf->len = 0; - } -} - -uint32_t HdcChannelBase::MallocChannel(HChannel *hOutChannel) -{ - auto hChannel = new HdcChannel(); - if (!hChannel) { - return 0; - } - uint32_t channelId = Base::GetRuntimeMSec(); - if (isServerOrClient) { - hChannel->serverOrClient = isServerOrClient; - ++channelId; // Use different value for serverForClient&client in per process - } - uv_tcp_init(loopMain, &hChannel->hWorkTCP); - ++hChannel->uvRef; - hChannel->hWorkThread = uv_thread_self(); - hChannel->hWorkTCP.data = hChannel; - hChannel->clsChannel = this; - hChannel->channelId = channelId; - AdminChannel(OP_ADD, channelId, hChannel); - *hOutChannel = hChannel; - WRITE_LOG(LOG_DEBUG, "Mallocchannel:%d", channelId); - return channelId; -} - -// work when libuv-handle at struct of HdcSession has all callback finished -void HdcChannelBase::FreeChannelFinally(uv_idle_t *handle) -{ - HChannel hChannel = (HChannel)handle->data; - HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; - if (hChannel->uvRef > 0) { - return; - } - thisClass->NotifyInstanceChannelFree(hChannel); - thisClass->AdminChannel(OP_REMOVE, hChannel->channelId, nullptr); - WRITE_LOG(LOG_DEBUG, "!!!FreeChannelFinally channelId:%d finish", hChannel->channelId); - if (!hChannel->serverOrClient) { - uv_stop(thisClass->loopMain); - } - delete hChannel; - Base::TryCloseHandle((const uv_handle_t *)handle, Base::CloseIdleCallback); -} - -void HdcChannelBase::FreeChannelContinue(HChannel hChannel) -{ - auto closeChannelHandle = [](uv_handle_t *handle) -> void { - HChannel hChannel = (HChannel)handle->data; - --hChannel->uvRef; - Base::TryCloseHandle((uv_handle_t *)handle); - }; - hChannel->availTailIndex = 0; - if (hChannel->ioBuf) { - delete[] hChannel->ioBuf; - hChannel->ioBuf = nullptr; - } - if (!hChannel->serverOrClient) { - Base::TryCloseHandle((uv_handle_t *)&hChannel->stdinTty, closeChannelHandle); - Base::TryCloseHandle((uv_handle_t *)&hChannel->stdoutTty, closeChannelHandle); - } - if (uv_is_closing((const uv_handle_t *)&hChannel->hWorkTCP)) { - --hChannel->uvRef; - } else { - Base::TryCloseHandle((uv_handle_t *)&hChannel->hWorkTCP, closeChannelHandle); - } - Base::IdleUvTask(loopMain, hChannel, FreeChannelFinally); -} - -void HdcChannelBase::FreeChannelOpeate(uv_timer_t *handle) -{ - HChannel hChannel = (HChannel)handle->data; - HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; - if (hChannel->sendRef > 0) { - return; - } - if (hChannel->hChildWorkTCP.loop) { - auto ctrl = HdcSessionBase::BuildCtrlString(SP_DEATCH_CHANNEL, hChannel->channelId, nullptr, 0); - thisClass->ChannelSendSessionCtrlMsg(ctrl, hChannel->targetSessionId); - auto callbackCheckFreeChannelContinue = [](uv_timer_t *handle) -> void { - HChannel hChannel = (HChannel)handle->data; - HdcChannelBase *thisClass = (HdcChannelBase *)hChannel->clsChannel; - if (!hChannel->childCleared) { - return; - } - Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseTimerCallback); - thisClass->FreeChannelContinue(hChannel); - }; - Base::TimerUvTask(thisClass->loopMain, hChannel, callbackCheckFreeChannelContinue); - } else { - thisClass->FreeChannelContinue(hChannel); - } - Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseTimerCallback); -} - -void HdcChannelBase::FreeChannel(const uint32_t channelId) -{ - HChannel hChannel = AdminChannel(OP_QUERY, channelId, nullptr); - if (!hChannel) { - return; - } - // Two cases: alloc in main thread, or work thread - if (hChannel->hWorkThread != uv_thread_self()) { - PushAsyncMessage(hChannel->channelId, ASYNC_FREE_SESSION, nullptr, 0); - return; - } - if (hChannel->isDead) { - return; - } - Base::TimerUvTask(loopMain, hChannel, FreeChannelOpeate, MINOR_TIMEOUT); // do immediately - hChannel->isDead = true; -} - -HChannel HdcChannelBase::AdminChannel(const uint8_t op, const uint32_t channelId, HChannel hInput) -{ - HChannel hRet = nullptr; - switch (op) { - case OP_ADD: - uv_rwlock_wrlock(&lockMapChannel); - mapChannel[channelId] = hInput; - uv_rwlock_wrunlock(&lockMapChannel); - break; - case OP_REMOVE: - uv_rwlock_wrlock(&lockMapChannel); - mapChannel.erase(channelId); - uv_rwlock_wrunlock(&lockMapChannel); - break; - case OP_QUERY: - uv_rwlock_rdlock(&lockMapChannel); - if (mapChannel.count(channelId)) { - hRet = mapChannel[channelId]; - } - uv_rwlock_rdunlock(&lockMapChannel); - break; - case OP_UPDATE: - uv_rwlock_wrlock(&lockMapChannel); - // remove old - mapChannel.erase(channelId); - mapChannel[hInput->channelId] = hInput; - uv_rwlock_wrunlock(&lockMapChannel); - break; - default: - break; - } - return hRet; -} -} \ No newline at end of file diff --git a/services/flashd/common/channel.h b/services/flashd/common/channel.h deleted file mode 100755 index 72b81813..00000000 --- a/services/flashd/common/channel.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_CHANNEL_H -#define HDC_CHANNEL_H -#include "common.h" - -namespace Hdc { -class HdcChannelBase { -public: - HdcChannelBase(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn); - virtual ~HdcChannelBase(); - HChannel AdminChannel(const uint8_t op, const uint32_t channelId, HChannel hInput); - static void AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf); - static void ReadStream(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf); - void PushAsyncMessage(const uint32_t channelId, const uint8_t method, const void *data, const int dataSize); - void WorkerPendding(); - void FreeChannel(const uint32_t channelId); - vector GetChannelHandshake(string &connectKey) const; - -protected: - struct ChannelHandShake { - char banner[12]; // must first index - union { - uint32_t channelId; - char connectKey[MAX_CONNECTKEY_SIZE]; - }; - } __attribute__((packed)); - uint32_t MallocChannel(HChannel *hOutChannel); - virtual int ReadChannel(HChannel hChannel, uint8_t *bufPtr, const int bytesIO) - { - return 0; - } - virtual void NotifyInstanceChannelFree(HChannel hChannel) {}; - void Send(const uint32_t channelId, uint8_t *bufPtr, const int size); - virtual bool ChannelSendSessionCtrlMsg(vector &ctrlMsg, uint32_t sessionId) - { - return true; // just server use - } - - string channelHostPort; - string channelHost; - uint16_t channelPort; - uv_loop_t *loopMain; - bool isServerOrClient; - uv_rwlock_t mainAsync; - uv_async_t asyncMainLoop; - list lstMainThreadOP; - -private: - static void MainAsyncCallback(uv_async_t *handle); - static void WriteCallback(uv_write_t *req, int status); - static void AsyncMainLoopTask(uv_idle_t *handle); - static void FreeChannelOpeate(uv_timer_t *handle); - static void FreeChannelFinally(uv_idle_t *handle); - void ClearChannels(); - void FreeChannelContinue(HChannel hChannel); - bool SetChannelTCPString(const string &addrString); - - uv_rwlock_t lockMapChannel; // protect mapChannel - map mapChannel; -}; -} // namespace Hdc - -#endif // HDC_CHANNEL_H \ No newline at end of file diff --git a/services/flashd/common/common.h b/services/flashd/common/common.h deleted file mode 100755 index e90125ba..00000000 --- a/services/flashd/common/common.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_COMMON_H -#define HDC_COMMON_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -using std::condition_variable; -using std::list; -using std::map; -using std::mutex; -using std::string; -using std::vector; - -// clang-format off -#include // libuv 1.35 -#ifdef HDC_HOST - -#ifdef HARMONY_PROJECT -#include -#else // NOT HARMONY_PROJECT -#include -#endif // END HARMONY_PROJECT - -#else // NOT HDC_HOST -#endif // HDC_HOST - -#ifndef _WIN32 -#include -#include -#endif - -#include - -#include "define.h" -#include "debug.h" -#include "base.h" -#include "task.h" -#include "channel.h" -#include "session.h" -#include "auth.h" - -#include "tcp.h" -#include "usb.h" -#include "file_descriptor.h" - -// clang-format on - -#endif // !defined(COMMON_H_INCLUDED) diff --git a/services/flashd/common/debug.cpp b/services/flashd/common/debug.cpp deleted file mode 100755 index 30b81c7e..00000000 --- a/services/flashd/common/debug.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "debug.h" -#include "base.h" - -namespace Hdc { -namespace Debug { - int WriteHexToDebugFile(const char *fileName, const uint8_t *buf, const int bufLen) - { - char pathName[BUF_SIZE_DEFAULT]; - if (snprintf_s(pathName, sizeof(pathName), sizeof(pathName) - 1, "/mnt/hgfs/vtmp/%s", fileName) < 0) { - return ERR_BUF_OVERFLOW; - } - string srcPath = pathName; - string resolvedPath = Base::CanonicalizeSpecPath(srcPath); - FILE *fp = fopen(resolvedPath.c_str(), "a+"); - if (fp == nullptr) { - if (snprintf_s(pathName, sizeof(pathName), sizeof(pathName) - 1, "/tmp/%s", fileName) < 0) { - WRITE_LOG(LOG_DEBUG, "Write hex to %s failed!", pathName); - return ERR_FILE_OPEN; - } - - srcPath = pathName; - resolvedPath = Base::CanonicalizeSpecPath(srcPath); - if ((fp = fopen(resolvedPath.c_str(), "a+")) == nullptr) { - WRITE_LOG(LOG_DEBUG, "Write hex to %s failed!", pathName); - return ERR_FILE_OPEN; - } - } - fwrite(buf, 1, bufLen, fp); - fflush(fp); - fclose(fp); - return RET_SUCCESS; - } - - int ReadHexFromDebugFile(const char *fileName, uint8_t *buf, const int bufLen) - { - char pathName[BUF_SIZE_DEFAULT]; - if (snprintf_s(pathName, sizeof(pathName), sizeof(pathName) - 1, "/mnt/hgfs/vtmp/%s", fileName) < 0) { - return ERR_BUF_OVERFLOW; - } - FILE *fp = fopen(pathName, "r"); - if (fp == nullptr) { - if (snprintf_s(pathName, sizeof(pathName), sizeof(pathName) - 1, "/tmp/%s", fileName) < 0 - || (fp = fopen(pathName, "r")) == nullptr) { - if (fp != nullptr) { - fclose(fp); - } - WRITE_LOG(LOG_DEBUG, "Write hex to %s failed!", pathName); - return ERR_FILE_WRITE; - } - } - struct stat statbuf; - stat(pathName, &statbuf); - int size = statbuf.st_size; - if (size > bufLen) { - fclose(fp); - return ERR_BUF_SIZE; - } - int ret = fread(buf, 1, size, fp); - fflush(fp); - fclose(fp); - if (ret != size) { - return ERR_FILE_READ; - } - return size; - } - - void DetermineThread(HSession hSession) - { - if (uv_thread_self() == hSession->hWorkThread) { - WRITE_LOG(LOG_WARN, "At main workthread"); - } else if (uv_thread_self() == hSession->hWorkChildThread) { - WRITE_LOG(LOG_WARN, "At child workthread"); - } else { - WRITE_LOG(LOG_WARN, "At unknow workthread"); - } - } - - int PrintfHexBuf(const uint8_t *buf, int bufLen) - { - int i = 0; - for (i = 0; i < bufLen; ++i) { - printf("0x%02x, ", buf[i]); - fflush(stdout); - } - printf("\r\n"); - fflush(stdout); - return 0; - } -} -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/debug.h b/services/flashd/common/debug.h deleted file mode 100755 index b14d1e10..00000000 --- a/services/flashd/common/debug.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_DEBUG_H -#define HDC_DEBUG_H -#include "common.h" - -namespace Hdc { -namespace Debug { - int WriteHexToDebugFile(const char *fileName, const uint8_t *buf, const int bufLen); - int ReadHexFromDebugFile(const char *fileName, uint8_t *buf, const int bufLen); - void DetermineThread(HSession hSession); - int PrintfHexBuf(const uint8_t *buf, int bufLen); -} -} // namespace Hdc - -#endif \ No newline at end of file diff --git a/services/flashd/common/define.h b/services/flashd/common/define.h deleted file mode 100755 index 0c1ddf0d..00000000 --- a/services/flashd/common/define.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_DEFINE_H -#define HDC_DEFINE_H -#include "define_plus.h" - -namespace Hdc { -// ############################## config ####################################### -constexpr uint8_t MINOR_TIMEOUT = 5; -constexpr uint8_t SIZE_THREAD_POOL = 16; -constexpr uint8_t GLOBAL_TIMEOUT = 30; -constexpr uint16_t DEFAULT_PORT = 8710; -constexpr uint16_t MAX_SIZE_IOBUF = 5120; // USB EP block max size about 10k, USBFFS_BULKSIZE 16384 -constexpr bool ENABLE_IO_CHECKSUM = false; -const string DEFAULT_SERVER_ADDR = "127.0.0.1:8710"; - -// ################################ macro define ################################### -constexpr uint8_t DWORD_SERIALIZE_SIZE = 4; -constexpr uint8_t CMD_ARG1_COUNT = 2; -constexpr uint8_t STREAM_MAIN = 0; // work at main thread -constexpr uint8_t STREAM_WORK = 1; // work at work thread -constexpr uint16_t BUF_SIZE_MICRO = 16; -constexpr uint16_t BUF_SIZE_TINY = 64; -constexpr uint16_t BUF_SIZE_SMALL = 256; -constexpr uint16_t BUF_SIZE_MEDIUM = 512; -constexpr uint16_t BUF_SIZE_DEFAULT = 1024; -constexpr uint16_t BUF_SIZE_DEFAULT2 = BUF_SIZE_DEFAULT * 2; -constexpr uint16_t BUF_SIZE_DEFAULT4 = BUF_SIZE_DEFAULT * 4; -constexpr uint16_t MAX_IP_PORT = 65535; -constexpr uint16_t MAX_CONNECTKEY_SIZE = 32; // usb sn/tcp ipport -constexpr uint16_t TIME_BASE = 1000; // time unit conversion base value -constexpr uint16_t AID_SHELL = 2000; -constexpr uint16_t UV_DEFAULT_INTERVAL = 250; // ms -constexpr uint16_t VER_PROTOCOL = 0x01; -constexpr uint16_t EXTRA_ALLOC_SIZE = 2048; -// double-word(hex)=[0]major[1][2]minor[3][4]version[5]fix(a-p)[6][7]reserve -constexpr uint32_t HDC_VERSION_NUMBER = 0x10101800; // 1.1.1b=0x10101100 -constexpr uint32_t HDC_BUF_MAX_BYTES = 1024000000; - -const string WHITE_SPACES = " \t\n\r"; -const string UT_TMP_PATH = "/tmp/hdc-ut"; -const string LOG_FILE_NAME = "hdc.log"; -const string SERVER_NAME = "HDCServer"; -const string STRING_EMPTY = ""; -const string HANDSHAKE_MESSAGE = "OHOS HDC"; // sep not char '-', not more than 11 bytes -const string PACKET_FLAG = "HW"; // must 2bytes -const string EMPTY_ECHO = "[Empty]"; -const string MESSAGE_INFO = "[Info]"; -const string MESSAGE_FAIL = "[Fail]"; -const string MESSAGE_SUCCESS = "[Success]"; -// input command -const string CMDSTR_SOFTWARE_VERSION = "version"; -const string CMDSTR_SOFTWARE_HELP = "help"; -const string CMDSTR_TARGET_DISCOVER = "discover"; -const string CMDSTR_SERVICE_START = "start"; -const string CMDSTR_SERVICE_KILL = "kill"; -const string CMDSTR_GENERATE_KEY = "keygen"; -const string CMDSTR_KILL_SERVER = "kserver"; -const string CMDSTR_KILL_DAEMON = "kdaemon"; -const string CMDSTR_LIST_TARGETS = "list targets"; -const string CMDSTR_CONNECT_TARGET = "tconn"; -const string CMDSTR_CONNECT_ANY = "any"; -const string CMDSTR_SHELL = "shell"; -const string CMDSTR_TARGET_REBOOT = "target boot"; -const string CMDSTR_TARGET_MOUNT = "target mount"; -const string CMDSTR_STARTUP_MODE = "smode"; -const string CMDSTR_TARGET_MODE = "tmode"; -const string CMDSTR_BUGREPORT = "bugreport"; -const string CMDSTR_HILOG = "hilog"; -const string CMDSTR_TMODE_USB = "usb"; -const string CMDSTR_TMODE_TCP = "tcp"; -const string CMDSTR_FILE_SEND = "file send"; -const string CMDSTR_FILE_RECV = "file recv"; -const string CMDSTR_FORWARD_FPORT = "fport"; -const string CMDSTR_FORWARD_RPORT = "rport"; -const string CMDSTR_APP_INSTALL = "install"; -const string CMDSTR_APP_UNINSTALL = "uninstall"; -const string CMDSTR_APP_SIDELOAD = "sideload"; -const string CMDSTR_LIST_JDWP = "jpid"; -const string CMDSTR_UPDATE_SYSTEM = "update"; -const string CMDSTR_FLASH_PARTITION = "flash"; -const string CMDSTR_ERASE_PARTITION = "erase"; -const string CMDSTR_FORMAT_PARTITION = "format"; -const string CMDSTR_INNER_ENABLE_KEEPALIVE = "alive"; -} // namespace Hdc -#endif // HDC_DEFINE_H diff --git a/services/flashd/common/define_plus.h b/services/flashd/common/define_plus.h deleted file mode 100755 index 0e4c22b7..00000000 --- a/services/flashd/common/define_plus.h +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef DEFINE_PLUS_H -#define DEFINE_PLUS_H - -namespace Hdc { -constexpr uint8_t LOG_LEVEL_FULL = 5; -// ############################# enum define ################################### -enum LogLevel { - LOG_OFF, - LOG_FATAL, - LOG_INFO, // default - LOG_WARN, - LOG_DEBUG, - LOG_FULL, - LOG_LAST = LOG_FULL, // tail, not use -}; -#define WRITE_LOG(x, y...) Base::PrintLogEx(__FILE__, __LINE__, x, y) - -enum MessageLevel { - MSG_FAIL, - MSG_INFO, - MSG_OK, -}; - -enum ConnType { CONN_USB = 0, CONN_TCP, CONN_SERIAL, CONN_BT }; -enum ConnStatus { STATUS_UNKNOW = 0, STATUS_READY, STATUS_CONNECTED, STATUS_OFFLINE }; - -enum OperateID { - OP_ADD, - OP_REMOVE, - OP_QUERY, - OP_GET_STRLIST, - OP_GET_STRLIST_FULL, - OP_GET_ANY, - OP_UPDATE, - OP_CLEAR, - OP_INIT, - OP_GET_ONLY -}; - -enum RetErrCode { - RET_SUCCESS = 0, - ERR_GENERIC = -1, - ERR_BUF_SIZE = -10000, - ERR_BUF_ALLOC, - ERR_BUF_OVERFLOW, - ERR_BUF_CHECK, - ERR_BUF_RESET, - ERR_BUF_COPY, - ERR_FILE_OPEN = -11000, - ERR_FILE_READ, - ERR_FILE_WRITE, - ERR_FILE_STAT, - ERR_FILE_PATH_CHECK, - ERR_PARM_FORMAT = -12000, - ERR_PARM_SIZE, - ERR_PARM_FAIL, - ERR_API_FAIL = -13000, - ERR_IO_FAIL = -14000, - ERR_IO_TIMEOUT, - ERR_IO_SOFT_RESET, - ERR_SESSION_NOFOUND = -15000, - ERR_SESSION_OFFLINE, - ERR_SESSION_DEAD, - ERR_HANDSHAKE_NOTMATCH = -16000, - ERR_HANDSHAKE_CONNECTKEY_FAILED, - ERR_HANDSHAKE_HANGUP_CHILD, - ERR_SOCKET_FAIL = -17000, - ERR_SOCKET_DUPLICATE, - ERR_MODULE_JDWP_FAILED = -18000, - ERR_UT_MODULE_NOTREADY = -19000, - ERR_UT_MODULE_WAITMAX, - ERR_THREAD_MUTEX_FAIL = -20000, - ERR_PROCESS_SUB_FAIL = -21000, - ERR_PRIVELEGE_NEED = -22000, -}; - -// Flags shared by multiple modules -enum AsyncEvent { - ASYNC_STOP_MAINLOOP = 0, - ASYNC_FREE_SESSION, -}; -enum InnerCtrlCommand { - SP_START_SESSION = 0, - SP_STOP_SESSION, - SP_ATTACH_CHANNEL, - SP_DEATCH_CHANNEL, - SP_JDWP_NEWFD, -}; - -enum HdcCommand { - // core commands types - CMD_KERNEL_HELP = 0, - CMD_KERNEL_HANDSHAKE, - CMD_KERNEL_CHANNEL_CLOSE, - CMD_KERNEL_SERVER_KILL, - CMD_KERNEL_TARGET_DISCOVER, - CMD_KERNEL_TARGET_LIST, - CMD_KERNEL_TARGET_ANY, - CMD_KERNEL_TARGET_CONNECT, - CMD_KERNEL_TARGET_DISCONNECT, - CMD_KERNEL_ECHO, - CMD_KERNEL_ECHO_RAW, - CMD_KERNEL_ENABLE_KEEPALIVE, - // One-pass simple commands - CMD_UNITY_EXECUTE = 1000, - CMD_UNITY_REMOUNT, - CMD_UNITY_REBOOT, - CMD_UNITY_RUNMODE, - CMD_UNITY_HILOG, - CMD_UNITY_TERMINATE, - CMD_UNITY_ROOTRUN, - CMD_UNITY_BUGREPORT_INIT, - CMD_UNITY_BUGREPORT_DATA, - CMD_UNITY_JPID, - // Shell commands types - CMD_SHELL_INIT = 2000, - CMD_SHELL_DATA, - // Forward commands types - CMD_FORWARD_INIT = 2500, - CMD_FORWARD_CHECK, - CMD_FORWARD_CHECK_RESULT, - CMD_FORWARD_ACTIVE_SLAVE, - CMD_FORWARD_ACTIVE_MASTER, - CMD_FORWARD_DATA, - CMD_FORWARD_FREE_CONTEXT, - CMD_FORWARD_LIST, - CMD_FORWARD_REMOVE, - CMD_FORWARD_SUCCESS, - // File commands - CMD_FILE_INIT = 3000, - CMD_FILE_CHECK, - CMD_FILE_BEGIN, - CMD_FILE_DATA, - CMD_FILE_FINISH, - CMD_APP_SIDELOAD, - // App commands - CMD_APP_INIT = 3500, - CMD_APP_CHECK, - CMD_APP_BEGIN, - CMD_APP_DATA, - CMD_APP_FINISH, - CMD_APP_UNINSTALL, - // update - CMD_UPDATER_UPDATE_INIT = 4000, - CMD_UPDATER_FLASH_INIT, - CMD_UPDATER_CHECK, - CMD_UPDATER_BEGIN, - CMD_UPDATER_DATA, - CMD_UPDATER_FINISH = 4005, - CMD_UPDATER_ERASE, - CMD_UPDATER_FORMAT, - CMD_UPDATER_PROGRESS -}; - -enum UsbProtocolOption { - USB_OPTION_TAIL = 1, - USB_OPTION_RESET = 2, - USB_OPTION_RESERVE4 = 4, - USB_OPTION_RESERVE8 = 8, - USB_OPTION_RESERVE16 = 16, -}; -// ################################### struct define ################################### -#pragma pack(push) -#pragma pack(1) - -struct USBHead { - uint8_t flag[2]; - uint8_t option; - uint32_t sessionId; - uint16_t dataSize; -}; - -struct AsyncParam { - void *context; // context=hsession or hchannel - uint32_t sid; // sessionId/channelId - void *thisClass; // caller's class ptr - uint16_t method; - int dataSize; - void *data; // put it in the last -}; - -struct TaskInformation { - uint8_t taskType; - uint32_t sessionId; - uint32_t channelId; - bool hasInitial; - bool taskStop; - bool taskFree; - bool serverOrDaemon; - uv_loop_t *runLoop; - void *taskClass; - void *ownerSessionClass; -}; -using HTaskInfo = TaskInformation *; - -#pragma pack(pop) - -struct HdcUSB { -#ifdef HDC_HOST - libusb_context *ctxUSB = nullptr; // child-use, main null - libusb_device *device; - libusb_device_handle *devHandle; - uint8_t interfaceNumber; - uint16_t retryCount; - // D2H device to host endpoint's address - uint8_t epDevice; - // H2D host to device endpoint's address - uint8_t epHost; - uint8_t devId; - uint8_t busId; - int32_t sizeEpBuf; - uint16_t wMaxPacketSize; - string serialNumber; - string usbMountPoint; - uint8_t *bufDevice; - uint8_t *bufHost; - - mutex lockDeviceHandle; - libusb_transfer *transferRecv; - bool recvIOComplete; - - mutex lockSend; - condition_variable cvTransferSend; - libusb_transfer *transferSend; - bool sendIOComplete; -#else - // usb accessory FunctionFS - // USB main thread use, sub-thread disable, sub-thread uses the main thread USB handle - int bulkOut; // EP1 device recv - int bulkIn; // EP2 device send -#endif - vector bufRecv; - bool resetIO; // if true, must break write and read,default false -}; -using HUSB = struct HdcUSB *; - -struct HdcSession { - bool serverOrDaemon; // instance of daemon or server - bool handshakeOK; // Is an expected peer side - bool isDead; - string connectKey; - uint8_t connType; // ConnType - uint32_t sessionId; - std::atomic sendRef; - uint8_t uvRef; // libuv handle ref -- just main thread now - uint8_t uvChildRef; // libuv handle ref -- just main thread now - bool childCleared; - map *mapTask; - // class ptr - void *classInstance; // HdcSessionBase instance, HdcServer or HdcDaemon - void *classModule; // Communicate module, TCP or USB instance,HdcDaemonUSB HdcDaemonTCP etc... - // io cache - int bufSize; // total buffer size - int availTailIndex; // buffer available data size - uint8_t *ioBuf; - // auth - list *listKey; // rsa private or publickey list - uint8_t authKeyIndex; - string tokenRSA; // SHA_DIGEST_LENGTH+1==21 - // child work - uv_loop_t childLoop; // run in work thread - // pipe0 in main thread(hdc server mainloop), pipe1 in work thread - uv_tcp_t ctrlPipe[2]; // control channel - int ctrlFd[2]; // control channel socketpair - // data channel(TCP with socket, USB with thread forward) - uv_tcp_t dataPipe[2]; - int dataFd[2]; // data channel socketpair - uv_tcp_t hChildWorkTCP; // work channel,separate thread for server/daemon - uv_os_sock_t fdChildWorkTCP; - // usb handle - HUSB hUSB; - // tcp handle - uv_tcp_t hWorkTCP; - uv_thread_t hWorkThread; - uv_thread_t hWorkChildThread; -}; -using HSession = struct HdcSession *; - -struct HdcChannel { - void *clsChannel; // ptr Class of serverForClient or client - uint32_t channelId; - string connectKey; - uv_tcp_t hWorkTCP; // work channel for client, forward channel for server - uv_thread_t hWorkThread; - uint8_t uvRef = 0; // libuv handle ref -- just main thread now - bool handshakeOK; - bool isDead; - bool serverOrClient; // client's channel/ server's channel - bool childCleared; - bool interactiveShellMode; // Is shell interactive mode - bool keepAlive; // channel will not auto-close by server - std::atomic sendRef; - uint32_t targetSessionId; - // child work - uv_tcp_t hChildWorkTCP; // work channel for server, no use in client - uv_os_sock_t fdChildWorkTCP; - // read io cache - int bufSize; // total buffer size - int availTailIndex; // buffer available data size - uint8_t *ioBuf; - // std - uv_tty_t stdinTty; - uv_tty_t stdoutTty; - char bufStd[128]; -}; -using HChannel = struct HdcChannel *; - -struct HdcDaemonInformation { - uint8_t connType; - uint8_t connStatus; - string connectKey; - string usbMountPoint; - string devName; - HSession hSession; -}; -using HDaemonInfo = struct HdcDaemonInformation *; - -struct HdcForwardInformation { - string taskString; - bool forwardDirection; // true for forward, false is reverse; - uint32_t sessionId; - uint32_t channelId; -}; -using HForwardInfo = struct HdcForwardInformation *; -} -#endif \ No newline at end of file diff --git a/services/flashd/common/file.cpp b/services/flashd/common/file.cpp deleted file mode 100755 index 4e3cd905..00000000 --- a/services/flashd/common/file.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "file.h" -#include "serial_struct.h" - -namespace Hdc { -HdcFile::HdcFile(HTaskInfo hTaskInfo) - : HdcTransferBase(hTaskInfo) -{ - commandBegin = CMD_FILE_BEGIN; - commandData = CMD_FILE_DATA; -} - -HdcFile::~HdcFile() -{ - WRITE_LOG(LOG_DEBUG, "~HdcFile"); -}; - -void HdcFile::StopTask() -{ - WRITE_LOG(LOG_DEBUG, "HdcFile StopTask"); - singalStop = true; -}; - -bool HdcFile::BeginTransfer(CtxFile *context, const string &command) -{ - int argc = 0; - bool ret = false; - char **argv = Base::SplitCommandToArgs(command.c_str(), &argc); - if (argc < CMD_ARG1_COUNT || argv == nullptr) { - LogMsg(MSG_FAIL, "Transfer path split failed"); - if (argv) { - delete[]((char *)argv); - } - return false; - } - if (!SetMasterParameters(context, command.c_str(), argc, argv)) { - delete[]((char *)argv); - return false; - } - do { - ++refCount; - uv_fs_open(loopTask, &context->fsOpenReq, context->localPath.c_str(), O_RDONLY, S_IWUSR | S_IRUSR, OnFileOpen); - context->master = true; - ret = true; - } while (false); - if (!ret) { - LogMsg(MSG_FAIL, "Transfer path failed, Master:%s Slave:%s", context->localPath.c_str(), - context->remotePath.c_str()); - } - delete[]((char *)argv); - return ret; -} - -bool HdcFile::SetMasterParameters(CtxFile *context, const char *command, int argc, char **argv) -{ - int srcArgvIndex = 0; - const string CMD_OPTION_TSTMP = "-a"; - const string CMD_OPTION_SYNC = "-sync"; - const string CMD_OPTION_ZIP = "-z"; - - for (int i = 0; i < argc - CMD_ARG1_COUNT; i++) { - if (argv[i] == CMD_OPTION_ZIP) { - context->transferConfig.compressType = COMPRESS_LZ4; - ++srcArgvIndex; - } else if (argv[i] == CMD_OPTION_SYNC) { - context->transferConfig.updateIfNew = true; - ++srcArgvIndex; - } else if (argv[i] == CMD_OPTION_TSTMP) { - // The time zone difference may cause the display time on the PC and the - // device to differ by several hours - // - // ls -al --full-time - context->transferConfig.holdTimestamp = true; - ++srcArgvIndex; - } else if (argv[i] == CMD_OPTION_CLIENTCWD) { - context->transferConfig.clientCwd = argv[i + 1]; - srcArgvIndex += CMD_ARG1_COUNT; // skip 2args - } else if (argv[i][0] == '-') { - LogMsg(MSG_FAIL, "Unknow file option: %s", argv[i]); - return false; - } - } - context->remotePath = argv[argc - 1]; - context->localPath = argv[argc - 2]; - if (taskInfo->serverOrDaemon) { - // master and server - ExtractRelativePath(context->transferConfig.clientCwd, context->localPath); - } - if (!Base::CheckDirectoryOrPath(context->localPath.c_str(), true, true)) { - LogMsg(MSG_FAIL, "Src not exist, path: %s", context->localPath.c_str()); - return false; - } - context->localName = Base::GetFullFilePath(context->localPath); - return true; -} - -void HdcFile::CheckMaster(CtxFile *context) -{ - string s = SerialStruct::SerializeToString(context->transferConfig); - SendToAnother(CMD_FILE_CHECK, (uint8_t *)s.c_str(), s.size()); -} - -void HdcFile::WhenTransferFinish(CtxFile *context) -{ - WRITE_LOG(LOG_DEBUG, "HdcTransferBase OnFileClose"); - uint8_t flag = 1; - SendToAnother(CMD_FILE_FINISH, &flag, 1); -} - -void HdcFile::TransferSummary(CtxFile *context) -{ - uint64_t nMSec = Base::GetRuntimeMSec() - context->transferBegin; - double fRate = static_cast(context->indexIO) / nMSec; // / /1000 * 1000 = 0 - LogMsg(MSG_OK, "FileTransfer finish, Size:%lld time:%lldms rate:%.2lfkB/s", context->indexIO, nMSec, fRate); -} - -bool HdcFile::SlaveCheck(uint8_t *payload, const int payloadSize) -{ - bool ret = true; - bool childRet = false; - // parse option - string serialStrring((char *)payload, payloadSize); - TransferConfig &stat = ctxNow.transferConfig; - SerialStruct::ParseFromString(stat, serialStrring); - ctxNow.fileSize = stat.fileSize; - ctxNow.localPath = stat.path; - ctxNow.master = false; - ctxNow.fsOpenReq.data = &ctxNow; - // check path - childRet = SmartSlavePath(stat.clientCwd, ctxNow.localPath, stat.optionalName.c_str()); - if (childRet && ctxNow.transferConfig.updateIfNew) { // file exist and option need update - // if is newer - uv_fs_t fs; - Base::ZeroStruct(fs.statbuf); - uv_fs_stat(nullptr, &fs, ctxNow.localPath.c_str(), nullptr); - uv_fs_req_cleanup(&fs); - if ((uint64_t)fs.statbuf.st_mtim.tv_sec >= ctxNow.transferConfig.mtime) { - LogMsg(MSG_FAIL, "Target file is the same date or newer,path: %s", ctxNow.localPath.c_str()); - return false; - } - } - // begin work - ++refCount; - uv_fs_open(loopTask, &ctxNow.fsOpenReq, ctxNow.localPath.c_str(), UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, - S_IWUSR | S_IRUSR, OnFileOpen); - ctxNow.transferBegin = Base::GetRuntimeMSec(); - return ret; -} - -bool HdcFile::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) -{ - HdcTransferBase::CommandDispatch(command, payload, payloadSize); - bool ret = true; - switch (command) { - case CMD_FILE_INIT: { // initial - string s = string((char *)payload, payloadSize); - ret = BeginTransfer(&ctxNow, s); - ctxNow.transferBegin = Base::GetRuntimeMSec(); - break; - } - case CMD_FILE_CHECK: { - ret = SlaveCheck(payload, payloadSize); - break; - } - case CMD_FILE_FINISH: { - if (*payload) { // close-step3 - --(*payload); - SendToAnother(CMD_FILE_FINISH, payload, 1); - ++refCount; - uv_fs_close(loopTask, &ctxNow.fsCloseReq, ctxNow.fsOpenReq.result, OnFileClose); - } else { // close-step3 - TransferSummary(&ctxNow); - TaskFinish(); - } - break; - } - default: - break; - } - return ret; -} -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/file_descriptor.cpp b/services/flashd/common/file_descriptor.cpp deleted file mode 100755 index 61886062..00000000 --- a/services/flashd/common/file_descriptor.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "file_descriptor.h" - -namespace Hdc { -HdcFileDescriptor::HdcFileDescriptor(uv_loop_t *loopIn, int fdToRead, void *callerContextIn, - CallBackWhenRead callbackReadIn, CmdResultCallback callbackFinishIn) -{ - loop = loopIn; - workContinue = true; - callbackFinish = callbackFinishIn; - callbackRead = callbackReadIn; - fdIO = fdToRead; - refIO = 0; - callerContext = callerContextIn; -} - -HdcFileDescriptor::~HdcFileDescriptor() -{ - if (refIO > 0) { - WRITE_LOG(LOG_FATAL, "~HdcFileDescriptor refIO > 0"); - } -} - -bool HdcFileDescriptor::ReadyForRelease() -{ - return refIO == 0; -} - -// just tryCloseFdIo = true, callback will be effect -void HdcFileDescriptor::StopWork(bool tryCloseFdIo, std::function closeFdCallback) -{ - workContinue = false; - callbackCloseFd = closeFdCallback; - if (tryCloseFdIo && refIO > 0) { - ++refIO; - reqClose.data = this; - uv_fs_close(loop, &reqClose, fdIO, [](uv_fs_t *req) { - auto thisClass = (HdcFileDescriptor *)req->data; - uv_fs_req_cleanup(req); - if (thisClass->callbackCloseFd != nullptr) { - thisClass->callbackCloseFd(); - } - --thisClass->refIO; - }); - } -}; - -void HdcFileDescriptor::OnFileIO(uv_fs_t *req) -{ - CtxFileIO *ctxIO = static_cast(req->data); - HdcFileDescriptor *thisClass = ctxIO->thisClass; - uint8_t *buf = ctxIO->bufIO; - bool bFinish = false; - bool fetalFinish = false; - - do { - if (req->result > 0) { - if (req->fs_type == UV_FS_READ) { - if (!thisClass->callbackRead(thisClass->callerContext, buf, req->result)) { - bFinish = true; - break; - } - thisClass->LoopRead(); - } else { - // fs_write - } - } else { - WRITE_LOG(LOG_DEBUG, "OnFileIO fd:%d failed:%s", thisClass->fdIO, uv_strerror(req->result)); - bFinish = true; - fetalFinish = true; - break; - } - } while (false); - uv_fs_req_cleanup(req); - delete[] buf; - delete ctxIO; - - --thisClass->refIO; - if (bFinish) { - thisClass->callbackFinish(thisClass->callerContext, fetalFinish, "OnRead finish"); - thisClass->workContinue = false; - } -} - -int HdcFileDescriptor::LoopRead() -{ - uv_buf_t iov; - int readMax = Base::GetMaxBufSize() * 1.2; - auto contextIO = new CtxFileIO(); - auto buf = new uint8_t[readMax](); - if (!contextIO || !buf) { - if (contextIO) { - delete contextIO; - } - if (buf) { - delete[] buf; - } - WRITE_LOG(LOG_FATAL, "Memory alloc failed"); - callbackFinish(callerContext, true, "Memory alloc failed"); - return -1; - } - uv_fs_t *req = &contextIO->fs; - contextIO->bufIO = buf; - contextIO->thisClass = this; - req->data = contextIO; - ++refIO; - iov = uv_buf_init((char *)buf, readMax); - uv_fs_read(loop, req, fdIO, &iov, 1, -1, OnFileIO); - return 0; -} - -bool HdcFileDescriptor::StartWork() -{ - if (LoopRead() < 0) { - return false; - } - return true; -} - -int HdcFileDescriptor::Write(uint8_t *data, int size) -{ - if (size > static_cast(HDC_BUF_MAX_BYTES)) { - size = static_cast(HDC_BUF_MAX_BYTES); - } - auto buf = new uint8_t[size]; - if (!buf) { - return -1; - } - memcpy_s(buf, size, data, size); - return WriteWithMem(buf, size); -} - -// Data's memory must be Malloc, and the callback FREE after this function is completed -int HdcFileDescriptor::WriteWithMem(uint8_t *data, int size) -{ - auto contextIO = new CtxFileIO(); - if (!contextIO) { - delete[] data; - WRITE_LOG(LOG_FATAL, "Memory alloc failed"); - callbackFinish(callerContext, true, "Memory alloc failed"); - return -1; - } - uv_fs_t *req = &contextIO->fs; - contextIO->bufIO = data; - contextIO->thisClass = this; - req->data = contextIO; - ++refIO; - - uv_buf_t iov = uv_buf_init((char *)data, size); - uv_fs_write(loop, req, fdIO, &iov, 1, -1, OnFileIO); - return size; -} -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/file_descriptor.h b/services/flashd/common/file_descriptor.h deleted file mode 100755 index 40311e71..00000000 --- a/services/flashd/common/file_descriptor.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_FILE_DESCRIPTOR_H -#define HDC_FILE_DESCRIPTOR_H -#include "common.h" - -namespace Hdc { -class HdcFileDescriptor { -public: - // callerContext, normalFinish, errorString - using CmdResultCallback = std::function; - // callerContext, readBuf, readIOByes - using CallBackWhenRead = std::function; - HdcFileDescriptor(uv_loop_t *loopIn, int fdToRead, void *callerContextIn, CallBackWhenRead callbackReadIn, - CmdResultCallback callbackFinishIn); - virtual ~HdcFileDescriptor(); - int Write(uint8_t *data, int size); - int WriteWithMem(uint8_t *data, int size); - - bool ReadyForRelease(); - bool StartWork(); - void StopWork(bool tryCloseFdIo, std::function closeFdCallback); - -protected: -private: - struct CtxFileIO { - uv_fs_t fs; - uint8_t *bufIO; - HdcFileDescriptor *thisClass; - }; - static void OnFileIO(uv_fs_t *req); - int LoopRead(); - - std::function callbackCloseFd; - CmdResultCallback callbackFinish; - CallBackWhenRead callbackRead; - uv_loop_t *loop; - uv_fs_t reqClose; - void *callerContext; - bool workContinue; - int fdIO; - int refIO; -}; -} // namespace Hdc - -#endif // HDC_FILE_DESCRIPTOR_H \ No newline at end of file diff --git a/services/flashd/common/file.h b/services/flashd/common/flash_define.h similarity index 43% rename from services/flashd/common/file.h rename to services/flashd/common/flash_define.h index 230d3f50..20361a07 100755 --- a/services/flashd/common/file.h +++ b/services/flashd/common/flash_define.h @@ -12,28 +12,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef HDC_FILE_TRANSFER_H -#define HDC_FILE_TRANSFER_H +#ifndef UPDATER_HDC_DEFINE_H +#define UPDATER_HDC_DEFINE_H #include "common.h" -#include "transfer.h" namespace Hdc { -class HdcFile : public HdcTransferBase { -public: - HdcFile(HTaskInfo hTaskInfo); - virtual ~HdcFile(); - void StopTask(); - bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); +const string CMDSTR_UPDATE_SYSTEM = "update"; +const string CMDSTR_FLASH_PARTITION = "flash"; +const string CMDSTR_ERASE_PARTITION = "erase"; +const string CMDSTR_FORMAT_PARTITION = "format"; -protected: -private: - bool SlaveCheck(uint8_t *payload, const int payloadSize); - void CheckMaster(CtxFile *context); - void WhenTransferFinish(CtxFile *context); - bool BeginTransfer(CtxFile *context, const string &command); - void TransferSummary(CtxFile *context); - bool SetMasterParameters(CtxFile *context, const char *command, int argc, char **argv); -}; -} // namespace Hdc +// update +const int CMD_UPDATER_UPDATE_INIT = CMD_APP_INIT + 200; +const int CMD_UPDATER_FLASH_INIT = CMD_UPDATER_UPDATE_INIT + 1; +const int CMD_UPDATER_CHECK = CMD_UPDATER_UPDATE_INIT + 2; +const int CMD_UPDATER_BEGIN = CMD_UPDATER_UPDATE_INIT + 3; +const int CMD_UPDATER_DATA = CMD_UPDATER_UPDATE_INIT + 4; +const int CMD_UPDATER_FINISH = CMD_UPDATER_UPDATE_INIT + 5; +const int CMD_UPDATER_ERASE = CMD_UPDATER_UPDATE_INIT + 6; +const int CMD_UPDATER_FORMAT = CMD_UPDATER_UPDATE_INIT + 7; +const int CMD_UPDATER_PROGRESS = CMD_UPDATER_UPDATE_INIT + 8; -#endif \ No newline at end of file +const int TASK_UPDATER = TASK_APP + 1; +} // namespace Hdc +#endif // UPDATER_HDC_DEFINE_H diff --git a/services/flashd/common/forward.cpp b/services/flashd/common/forward.cpp deleted file mode 100755 index b096cbb9..00000000 --- a/services/flashd/common/forward.cpp +++ /dev/null @@ -1,789 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "forward.h" -#include "base.h" - -namespace Hdc { -HdcForwardBase::HdcForwardBase(HTaskInfo hTaskInfo) - : HdcTaskBase(hTaskInfo) -{ -} - -HdcForwardBase::~HdcForwardBase() -{ - WRITE_LOG(LOG_DEBUG, "~HdcForwardBase"); -}; - -bool HdcForwardBase::ReadyForRelease() -{ - if (!HdcTaskBase::ReadyForRelease()) { - return false; - } - return true; -} - -void HdcForwardBase::StopTask() -{ - map::iterator iter; - for (iter = mapCtxPoint.begin(); iter != mapCtxPoint.end(); ++iter) { - HCtxForward ctx = iter->second; - FreeContext(ctx, 0, false); - } - // FREECONTEXT in the STOP is triggered by the other party sector, no longer notifying each other. - mapCtxPoint.clear(); -}; - -void HdcForwardBase::OnAccept(uv_stream_t *server, HCtxForward ctxClient, uv_stream_t *client) -{ - HCtxForward ctxListen = (HCtxForward)server->data; - char buf[BUF_SIZE_DEFAULT] = { 0 }; - bool ret = false; - while (true) { - if (uv_accept(server, client)) { - break; - } - ctxClient->type = ctxListen->type; - ctxClient->remoteParamenters = ctxListen->remoteParamenters; - int maxSize = sizeof(buf) - FORWARD_PARAMENTER_BUFSIZE; - // clang-format off - if (snprintf_s(buf + FORWARD_PARAMENTER_BUFSIZE, maxSize, maxSize - 1, "%s", - ctxClient->remoteParamenters.c_str()) < 0) { - break; - } - // clang-format on - // pre 8bytes preserve for param bits - SendToTask(ctxClient->id, CMD_FORWARD_ACTIVE_SLAVE, (uint8_t *)buf, - strlen(buf + FORWARD_PARAMENTER_BUFSIZE) + 9); - ret = true; - break; - } - if (!ret) { - FreeContext(ctxClient, 0, false); - } -} - -void HdcForwardBase::ListenCallback(uv_stream_t *server, const int status) -{ - HCtxForward ctxListen = (HCtxForward)server->data; - HdcForwardBase *thisClass = ctxListen->thisClass; - uv_stream_t *client = nullptr; - - if (status == -1 || !ctxListen->ready) { - thisClass->FreeContext(ctxListen, 0, false); - thisClass->TaskFinish(); - return; - } - HCtxForward ctxClient = (HCtxForward)thisClass->MallocContext(true); - if (!ctxClient) { - return; - } - if (FORWARD_TCP == ctxListen->type) { - uv_tcp_init(ctxClient->thisClass->loopTask, &ctxClient->tcp); - client = (uv_stream_t *)&ctxClient->tcp; - } else { - // FORWARD_ABSTRACT, FORWARD_RESERVED, FORWARD_FILESYSTEM, - uv_pipe_init(ctxClient->thisClass->loopTask, &ctxClient->pipe, 0); - client = (uv_stream_t *)&ctxClient->pipe; - } - thisClass->OnAccept(server, ctxClient, client); -} - -void *HdcForwardBase::MallocContext(bool masterSlave) -{ - HCtxForward ctx = nullptr; - if ((ctx = new ContextForward()) == nullptr) { - return nullptr; - } - ctx->id = Base::GetRuntimeMSec(); - ctx->masterSlave = masterSlave; - ctx->thisClass = this; - ctx->fdClass = nullptr; - ctx->tcp.data = ctx; - ctx->pipe.data = ctx; - AdminContext(OP_ADD, ctx->id, ctx); - refCount++; - return ctx; -} - -void HdcForwardBase::FreeContextCallBack(HCtxForward ctx) -{ - AdminContext(OP_REMOVE, ctx->id, nullptr); - Base::DoNextLoop(loopTask, ctx, [](const uint8_t flag, string &msg, const void *data) { - HCtxForward ctx = (HCtxForward)data; - delete ctx; - }); - --refCount; -} - -void HdcForwardBase::FreeJDWP(HCtxForward ctx) -{ - if (ctx->fd > 0) { - close(ctx->fd); - } - if (ctx->fdClass) { - ctx->fdClass->StopWork(false, nullptr); - - auto funcReqClose = [](uv_idle_t *handle) -> void { - uv_close_cb funcIdleHandleClose = [](uv_handle_t *handle) -> void { - HCtxForward ctx = (HCtxForward)handle->data; - ctx->thisClass->FreeContextCallBack(ctx); - delete (uv_idle_t *)handle; - }; - HCtxForward ctx = (HCtxForward)handle->data; - if (ctx->fdClass->ReadyForRelease()) { - delete ctx->fdClass; - ctx->fdClass = nullptr; - Base::TryCloseHandle((uv_handle_t *)handle, funcIdleHandleClose); - } - }; - Base::IdleUvTask(loopTask, ctx, funcReqClose); - } -} - -void HdcForwardBase::FreeContext(HCtxForward ctxIn, const uint32_t id, bool bNotifyRemote) -{ - WRITE_LOG(LOG_DEBUG, "FreeContext bNotifyRemote:%d %p", bNotifyRemote, ctxIn); - HCtxForward ctx = nullptr; - if (!ctxIn) { - if (!(ctx = (HCtxForward)AdminContext(OP_QUERY, id, nullptr))) { - WRITE_LOG(LOG_DEBUG, "Query id failed"); - return; - } - } else { - ctx = ctxIn; - } - if (ctx->finish) { - return; - } - if (bNotifyRemote) { - SendToTask(ctx->id, CMD_FORWARD_FREE_CONTEXT, nullptr, 0); - } - uv_close_cb funcHandleClose = [](uv_handle_t *handle) -> void { - HCtxForward ctx = (HCtxForward)handle->data; - ctx->thisClass->FreeContextCallBack(ctx); - }; - switch (ctx->type) { - case FORWARD_TCP: - case FORWARD_JDWP: - Base::TryCloseHandle((uv_handle_t *)&ctx->tcp, true, funcHandleClose); - break; - case FORWARD_ABSTRACT: - case FORWARD_RESERVED: - case FORWARD_FILESYSTEM: - Base::TryCloseHandle((uv_handle_t *)&ctx->pipe, true, funcHandleClose); - break; - case FORWARD_DEVICE: { - FreeJDWP(ctx); - break; - } - default: - break; - } - ctx->finish = true; -} - -bool HdcForwardBase::SendToTask(const uint32_t cid, const uint16_t command, uint8_t *bufPtr, const int bufSize) -{ - bool ret = false; - // usually MAX_SIZE_IOBUF*2 from HdcFileDescriptor maxIO - if (bufSize > Base::GetMaxBufSize() * 2) { - return false; - } - auto newBuf = new uint8_t[bufSize + 4]; - if (!newBuf) { - return false; - } - *(uint32_t *)(newBuf) = htonl(cid); - if (bufSize > 0 && bufPtr != nullptr && memcpy_s(newBuf + 4, bufSize, bufPtr, bufSize) != EOK) { - delete[] newBuf; - return false; - } - ret = SendToAnother(command, newBuf, bufSize + 4); - delete[] newBuf; - return ret; -} - -// Forward flow is small and frequency is fast -void HdcForwardBase::AllocForwardBuf(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf) -{ - const uint16_t size = 1492 - 256; // For layer 3, the default MTU is 1492 bytes. reserve hdc header 256 bytes - buf->base = (char *)new char[size]; - if (buf->base) { - buf->len = size - 1; - } else { - WRITE_LOG(LOG_WARN, "AllocForwardBuf == null"); - } -} - -void HdcForwardBase::ReadForwardBuf(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) -{ - HCtxForward ctx = (HCtxForward)stream->data; - if (nread < 0) { - ctx->thisClass->FreeContext(ctx, 0, true); - return; - } - ctx->thisClass->SendToTask(ctx->id, CMD_FORWARD_DATA, (uint8_t *)buf->base, nread); - // clear - delete[] buf->base; -} - -void HdcForwardBase::ConnectTarget(uv_connect_t *connection, int status) -{ - HCtxForward ctx = (HCtxForward)connection->data; - HdcForwardBase *thisClass = ctx->thisClass; - delete connection; - if (status < 0) { - WRITE_LOG(LOG_WARN, "Forward connect result:%d error:%s", status, uv_err_name(status)); - } - thisClass->SetupPointContinue(ctx, status); -} - -bool HdcForwardBase::CheckNodeInfo(const char *nodeInfo, string as[2]) -{ - char bufString[BUF_SIZE_MEDIUM]; - if (!strchr(nodeInfo, ':')) { - return false; - } - if (EOK != strcpy_s(bufString, sizeof(bufString), nodeInfo)) { - return false; - } - if (*strchr(bufString, ':')) { - *strchr(bufString, ':') = '\0'; - } else { - return false; - } - as[0] = bufString; - as[1] = bufString + strlen(bufString) + 1; - if (as[0].size() > BUF_SIZE_SMALL || as[1].size() > BUF_SIZE_SMALL) { - return false; - } - if (as[0] == "tcp") { - int port = atoi(as[1].c_str()); - if (port <= 0 || port > MAX_IP_PORT) { - return false; - } - } - return true; -} - -bool HdcForwardBase::SetupPointContinue(HCtxForward ctx, int status) -{ - if (ctx->checkPoint) { - // send to active - uint8_t flag = status > 0; - SendToTask(ctx->id, CMD_FORWARD_CHECK_RESULT, &flag, 1); - FreeContext(ctx, 0, false); - return true; - } - if (status < 0) { - FreeContext(ctx, 0, true); - return false; - } - // send to active - if (!SendToTask(ctx->id, CMD_FORWARD_ACTIVE_MASTER, nullptr, 0)) { - FreeContext(ctx, 0, true); - return false; - } - return DoForwardBegin(ctx); -} - -bool HdcForwardBase::DetechForwardType(HCtxForward ctxPoint) -{ - string &sFType = ctxPoint->localArgs[0]; - string &sNodeCfg = ctxPoint->localArgs[1]; - // string to enum - if (sFType == "tcp") { - ctxPoint->type = FORWARD_TCP; - } else if (sFType == "dev") { - ctxPoint->type = FORWARD_DEVICE; - } else if (sFType == "localabstract") { - // daemon shell: /system/bin/socat abstract-listen:linux-abstract - - // daemon shell: /system/bin/socat - abstract-connect:linux-abstract - // host: hdc_std fport tcp:8080 localabstract:linux-abstract - ctxPoint->type = FORWARD_ABSTRACT; - } else if (sFType == "localreserved") { - sNodeCfg = HARMONY_RESERVED_SOCKET_PREFIX + sNodeCfg; - ctxPoint->type = FORWARD_RESERVED; - } else if (sFType == "localfilesystem") { - sNodeCfg = FILESYSTEM_SOCKET_PREFIX + sNodeCfg; - ctxPoint->type = FORWARD_FILESYSTEM; - } else if (sFType == "jdwp") { - ctxPoint->type = FORWARD_JDWP; - } else { - return false; - } - return true; -} - -bool HdcForwardBase::SetupTCPPoint(HCtxForward ctxPoint) -{ - string &sNodeCfg = ctxPoint->localArgs[1]; - int port = atoi(sNodeCfg.c_str()); - ctxPoint->tcp.data = ctxPoint; - uv_tcp_init(loopTask, &ctxPoint->tcp); - struct sockaddr_in addr; - if (ctxPoint->masterSlave) { - uv_ip4_addr("0.0.0.0", port, &addr); // loop interface - uv_tcp_bind(&ctxPoint->tcp, (const struct sockaddr *)&addr, 0); - if (uv_listen((uv_stream_t *)&ctxPoint->tcp, 4, ListenCallback)) { - ctxPoint->lastError = "TCP Port listen failed at " + sNodeCfg; - return false; - } - } else { - uv_ip4_addr("127.0.0.1", port, &addr); // loop interface - uv_connect_t *conn = new uv_connect_t(); - conn->data = ctxPoint; - uv_tcp_connect(conn, (uv_tcp_t *)&ctxPoint->tcp, (const struct sockaddr *)&addr, ConnectTarget); - } - return true; -} - -bool HdcForwardBase::SetupDevicePoint(HCtxForward ctxPoint) -{ - uint8_t flag = 1; - string &sNodeCfg = ctxPoint->localArgs[1]; - string resolvedPath = Base::CanonicalizeSpecPath(sNodeCfg); - if ((ctxPoint->fd = open(resolvedPath.c_str(), O_RDWR)) < 0) { - ctxPoint->lastError = "Open unix-dev failed"; - flag = -1; - } - auto funcRead = [&](const void *a, uint8_t *b, const int c) -> bool { - HCtxForward ctx = (HCtxForward)a; - return SendToTask(ctx->id, CMD_FORWARD_DATA, b, c); - }; - auto funcFinish = [&](const void *a, const bool b, const string c) -> bool { - HCtxForward ctx = (HCtxForward)a; - WRITE_LOG(LOG_DEBUG, "Error ReadForwardBuf dev,ret:%d reson:%s", b, c.c_str()); - FreeContext(ctx, 0, true); - return false; - }; - ctxPoint->fdClass = new HdcFileDescriptor(loopTask, ctxPoint->fd, ctxPoint, funcRead, funcFinish); - SetupPointContinue(ctxPoint, flag); - return true; -} - -bool HdcForwardBase::LocalAbstractConnect(uv_pipe_t *pipe, string &sNodeCfg) -{ - bool abstractRet = false; -#ifndef _WIN32 - int s = 0; - do { - if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { - break; - } - fcntl(s, F_SETFD, FD_CLOEXEC); - struct sockaddr_un addr; - Base::ZeroStruct(addr); - int addrLen = sNodeCfg.size() + offsetof(struct sockaddr_un, sun_path) + 1; - addr.sun_family = AF_LOCAL; - addr.sun_path[0] = 0; - - if (memcpy_s(addr.sun_path + 1, sizeof(addr.sun_path) - 1, sNodeCfg.c_str(), sNodeCfg.size()) != EOK) { - break; - }; - // local connect, ignore timeout - if (connect(s, (struct sockaddr *)&addr, addrLen) < 0) { - break; - } - if (uv_pipe_open(pipe, s)) { - break; - } - abstractRet = true; - } while (false); - if (!abstractRet && s > 0) { - close(s); - } -#endif - return abstractRet; -} - -bool HdcForwardBase::SetupFilePoint(HCtxForward ctxPoint) -{ - string &sNodeCfg = ctxPoint->localArgs[1]; - ctxPoint->pipe.data = ctxPoint; - uv_pipe_init(loopTask, &ctxPoint->pipe, 0); - if (ctxPoint->masterSlave) { - if (ctxPoint->type == FORWARD_RESERVED || ctxPoint->type == FORWARD_FILESYSTEM) { - unlink(sNodeCfg.c_str()); - } - if (uv_pipe_bind(&ctxPoint->pipe, sNodeCfg.c_str())) { - ctxPoint->lastError = "Unix pipe bind failed"; - return false; - } - if (uv_listen((uv_stream_t *)&ctxPoint->pipe, 4, ListenCallback)) { - ctxPoint->lastError = "Unix pipe listen failed"; - return false; - } - } else { - uv_connect_t *connect = new uv_connect_t(); - connect->data = ctxPoint; - if (ctxPoint->type == FORWARD_ABSTRACT) { - bool abstractRet = LocalAbstractConnect(&ctxPoint->pipe, sNodeCfg); - SetupPointContinue(ctxPoint, abstractRet ? 0 : -1); - if (!abstractRet) { - ctxPoint->lastError = "LocalAbstractConnect failed"; - return false; - } - } else { - uv_pipe_connect(connect, &ctxPoint->pipe, sNodeCfg.c_str(), ConnectTarget); - } - } - return true; -} - -bool HdcForwardBase::SetupPoint(HCtxForward ctxPoint) -{ - bool ret = true; - if (!DetechForwardType(ctxPoint)) { - return false; - } - switch (ctxPoint->type) { - case FORWARD_TCP: - if (!SetupTCPPoint(ctxPoint)) { - ret = false; - }; - break; -#ifndef _WIN32 - case FORWARD_DEVICE: - if (!SetupDevicePoint(ctxPoint)) { - ret = false; - }; - break; - case FORWARD_JDWP: - if (!SetupJdwpPoint(ctxPoint)) { - ret = false; - }; - break; - case FORWARD_ABSTRACT: - case FORWARD_RESERVED: - case FORWARD_FILESYSTEM: - if (!SetupFilePoint(ctxPoint)) { - ret = false; - }; - break; -#else - case FORWARD_DEVICE: - case FORWARD_JDWP: - case FORWARD_ABSTRACT: - case FORWARD_RESERVED: - case FORWARD_FILESYSTEM: - ctxPoint->lastError = "Not supoort forward-type"; - ret = false; - break; -#endif - default: - ctxPoint->lastError = "Not supoort forward-type"; - ret = false; - break; - } - return ret; -} - -bool HdcForwardBase::BeginForward(const char *command, string &sError) -{ - bool ret = false; - int argc = 0; - char bufString[BUF_SIZE_SMALL] = ""; - HCtxForward ctxPoint = (HCtxForward)MallocContext(true); - if (!ctxPoint) { - WRITE_LOG(LOG_FATAL, "MallocContext failed"); - return false; - } - char **argv = Base::SplitCommandToArgs(command, &argc); - while (true) { - if (argc < CMD_ARG1_COUNT) { - break; - } - if (strlen(argv[0]) > BUF_SIZE_SMALL || strlen(argv[1]) > BUF_SIZE_SMALL) { - break; - } - if (!CheckNodeInfo(argv[0], ctxPoint->localArgs)) { - break; - } - if (!CheckNodeInfo(argv[1], ctxPoint->remoteArgs)) { - break; - } - ctxPoint->remoteParamenters = argv[1]; - if (!SetupPoint(ctxPoint)) { - break; - } - - ret = true; - break; - } - sError = ctxPoint->lastError; - if (ret) { - // First 8-byte parameter bit - int maxBufSize = sizeof(bufString) - FORWARD_PARAMENTER_BUFSIZE; - if (snprintf_s(bufString + FORWARD_PARAMENTER_BUFSIZE, maxBufSize, maxBufSize - 1, "%s", argv[1]) > 0) { - SendToTask(ctxPoint->id, CMD_FORWARD_CHECK, (uint8_t *)bufString, - FORWARD_PARAMENTER_BUFSIZE + strlen(bufString + FORWARD_PARAMENTER_BUFSIZE) + 1); - taskCommand = command; - } - } - if (argv) { - delete[]((char *)argv); - } - return ret; -} - -inline bool HdcForwardBase::FilterCommand(uint8_t *bufCmdIn, uint32_t *idOut, uint8_t **pContentBuf) -{ - *pContentBuf = bufCmdIn + DWORD_SERIALIZE_SIZE; - *idOut = ntohl(*(uint32_t *)bufCmdIn); - return true; -} - -bool HdcForwardBase::SlaveConnect(uint8_t *bufCmd, bool bCheckPoint, string &sError) -{ - bool ret = false; - char *content = nullptr; - uint32_t idSlaveOld = 0; - HCtxForward ctxPoint = (HCtxForward)MallocContext(false); - if (!ctxPoint) { - WRITE_LOG(LOG_FATAL, "MallocContext failed"); - return false; - } - idSlaveOld = ctxPoint->id; - ctxPoint->checkPoint = bCheckPoint; - // refresh another id,8byte param - FilterCommand(bufCmd, &ctxPoint->id, (uint8_t **)&content); - AdminContext(OP_UPDATE, idSlaveOld, ctxPoint); - content += FORWARD_PARAMENTER_BUFSIZE; - if (!CheckNodeInfo(content, ctxPoint->localArgs)) { - return false; - } - if ((ctxPoint->checkPoint && slaveCheckWhenBegin) || !ctxPoint->checkPoint) { - if (!SetupPoint(ctxPoint)) { - WRITE_LOG(LOG_FATAL, "SetupPoint failed"); - goto Finish; - } - sError = ctxPoint->lastError; - } else { - SetupPointContinue(ctxPoint, 0); - } - ret = true; -Finish: - if (!ret) { - FreeContext(ctxPoint, 0, true); - } - return ret; -} - -bool HdcForwardBase::DoForwardBegin(HCtxForward ctx) -{ - switch (ctx->type) { - case FORWARD_TCP: - case FORWARD_JDWP: // jdwp use tcp ->socketpair->jvm - uv_tcp_nodelay((uv_tcp_t *)&ctx->tcp, 1); - uv_read_start((uv_stream_t *)&ctx->tcp, AllocForwardBuf, ReadForwardBuf); - break; - case FORWARD_ABSTRACT: - case FORWARD_RESERVED: - case FORWARD_FILESYSTEM: - uv_read_start((uv_stream_t *)&ctx->pipe, AllocForwardBuf, ReadForwardBuf); - break; - case FORWARD_DEVICE: { - ctx->fdClass->StartWork(); - break; - } - default: - break; - } - ctx->ready = true; - return true; -} - -void *HdcForwardBase::AdminContext(const uint8_t op, const uint32_t id, HCtxForward hInput) -{ - void *hRet = nullptr; - map &mapCtx = mapCtxPoint; - switch (op) { - case OP_ADD: - mapCtx[id] = hInput; - break; - case OP_REMOVE: - mapCtx.erase(id); - break; - case OP_QUERY: - if (mapCtx.count(id)) { - hRet = mapCtx[id]; - } - break; - case OP_UPDATE: - mapCtx.erase(id); - mapCtx[hInput->id] = hInput; - break; - default: - break; - } - return hRet; -} - -void HdcForwardBase::SendCallbackForwardBuf(uv_write_t *req, int status) -{ - ContextForwardIO *ctxIO = (ContextForwardIO *)req->data; - HCtxForward ctx = (HCtxForward)ctxIO->ctxForward; - if (status < 0 && !ctx->finish) { - WRITE_LOG(LOG_DEBUG, "SendCallbackForwardBuf ctx->type:%d, status:%d finish", ctx->type, status); - ctx->thisClass->FreeContext(ctx, 0, true); - } - delete[] ctxIO->bufIO; - delete ctxIO; - delete req; -} - -int HdcForwardBase::SendForwardBuf(HCtxForward ctx, uint8_t *bufPtr, const int size) -{ - int nRet = 0; - if (size > static_cast(HDC_BUF_MAX_BYTES)) { - return -1; - } - auto pDynBuf = new uint8_t[size]; - if (!pDynBuf) { - return -1; - } - memcpy_s(pDynBuf, size, bufPtr, size); - if (FORWARD_DEVICE == ctx->type) { - nRet = ctx->fdClass->WriteWithMem(pDynBuf, size); - } else { - auto ctxIO = new ContextForwardIO(); - if (!ctxIO) { - delete[] pDynBuf; - return -1; - } - ctxIO->ctxForward = ctx; - ctxIO->bufIO = pDynBuf; - if (FORWARD_TCP == ctx->type || FORWARD_JDWP == ctx->type) { - nRet = Base::SendToStreamEx((uv_stream_t *)&ctx->tcp, pDynBuf, size, nullptr, - (void *)SendCallbackForwardBuf, (void *)ctxIO); - } else { - // FORWARD_ABSTRACT, FORWARD_RESERVED, FORWARD_FILESYSTEM, - nRet = Base::SendToStreamEx((uv_stream_t *)&ctx->pipe, pDynBuf, size, nullptr, - (void *)SendCallbackForwardBuf, (void *)ctxIO); - } - } - return nRet; -} - -bool HdcForwardBase::CommandForwardCheckResult(HCtxForward ctx, uint8_t *payload) -{ - bool ret = true; - bool bCheck = (bool)payload; - LogMsg(bCheck ? MSG_OK : MSG_FAIL, "Forwardport result:%s", bCheck ? "OK" : "Failed"); - if (bCheck) { - string mapInfo = taskInfo->serverOrDaemon ? "1|" : "0|"; - mapInfo += taskCommand; - ctx->ready = true; - ServerCommand(CMD_FORWARD_SUCCESS, (uint8_t *)mapInfo.c_str(), mapInfo.size() + 1); - } else { - ret = false; - FreeContext(ctx, 0, false); - } - return ret; -} - -bool HdcForwardBase::ForwardCommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) -{ - bool ret = true; - uint8_t *pContent = nullptr; - int sizeContent = 0; - uint32_t id = 0; - HCtxForward ctx = nullptr; - FilterCommand(payload, &id, &pContent); - sizeContent = payloadSize - DWORD_SERIALIZE_SIZE; - if (!(ctx = (HCtxForward)AdminContext(OP_QUERY, id, nullptr))) { - WRITE_LOG(LOG_WARN, "Query id failed"); - return false; - } - switch (command) { - case CMD_FORWARD_CHECK_RESULT: { - ret = CommandForwardCheckResult(ctx, payload); - break; - } - case CMD_FORWARD_ACTIVE_MASTER: { - ret = DoForwardBegin(ctx); - break; - } - case CMD_FORWARD_DATA: { - if (ctx->finish) { - break; - } - if (SendForwardBuf(ctx, pContent, sizeContent) < 0) { - FreeContext(ctx, 0, true); - } - break; - } - case CMD_FORWARD_FREE_CONTEXT: { - FreeContext(ctx, 0, false); - break; - } - default: - ret = false; - break; - } - if (!ret) { - if (ctx) { - FreeContext(ctx, 0, true); - } else { - WRITE_LOG(LOG_DEBUG, "ctx==nullptr raw free"); - TaskFinish(); - } - } - return ret; -} - -bool HdcForwardBase::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) -{ - bool ret = true; - string sError; - // prepare - if (CMD_FORWARD_INIT == command) { - if (!BeginForward((char *)(payload), sError)) { - ret = false; - goto Finish; - } - return true; - } else if (CMD_FORWARD_CHECK == command) { - // Detect remote if it's reachable - if (!SlaveConnect(payload, true, sError)) { - ret = false; - goto Finish; - } - return true; - } else if (CMD_FORWARD_ACTIVE_SLAVE == command) { - // slave connect target port when activating - if (!SlaveConnect(payload, false, sError)) { - ret = false; - goto Finish; - } - return true; - } - if (!ForwardCommandDispatch(command, payload, payloadSize)) { - ret = false; - goto Finish; - } -Finish: - if (!ret) { - if (!sError.size()) { - LogMsg(MSG_FAIL, "Forward parament failed"); - } else { - LogMsg(MSG_FAIL, (char *)sError.c_str()); - WRITE_LOG(LOG_WARN, (char *)sError.c_str()); - } - } - return ret; -} -} // namespace Hdc diff --git a/services/flashd/common/forward.h b/services/flashd/common/forward.h deleted file mode 100755 index 9baf4702..00000000 --- a/services/flashd/common/forward.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_FORWARD_H -#define HDC_FORWARD_H -#include "common.h" - -namespace Hdc { -class HdcForwardBase : public HdcTaskBase { -public: - HdcForwardBase(HTaskInfo hTaskInfo); - virtual ~HdcForwardBase(); - bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); - bool BeginForward(const char *command, string &sError); - void StopTask(); - bool ReadyForRelease(); - -protected: - enum FORWARD_TYPE { - FORWARD_TCP, - FORWARD_DEVICE, - FORWARD_JDWP, - FORWARD_ABSTRACT, - FORWARD_RESERVED, - FORWARD_FILESYSTEM, - }; - struct ContextForward { - FORWARD_TYPE type; - bool masterSlave; - bool checkPoint; - bool ready; - bool finish; - int fd; - uint32_t id; - uv_tcp_t tcp; - uv_pipe_t pipe; - HdcFileDescriptor *fdClass; - HdcForwardBase *thisClass; - string path; - string lastError; - string localArgs[2]; - string remoteArgs[2]; - string remoteParamenters; - }; - using HCtxForward = struct ContextForward *; - struct ContextForwardIO { - HCtxForward ctxForward; - uint8_t *bufIO; - }; - - virtual bool SetupJdwpPoint(HCtxForward ctxPoint) - { - return false; - } - bool SetupPointContinue(HCtxForward ctx, int status); - -private: - static void ListenCallback(uv_stream_t *server, const int status); - static void ConnectTarget(uv_connect_t *connection, int status); - static void ReadForwardBuf(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); - static void AllocForwardBuf(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf); - static void SendCallbackForwardBuf(uv_write_t *req, int status); - static void OnFdRead(uv_fs_t *req); - - bool SetupPoint(HCtxForward ctxPoint); - void *MallocContext(bool masterSlave); - bool SlaveConnect(uint8_t *bufCmd, bool bCheckPoint, string &sError); - bool SendToTask(const uint32_t cid, const uint16_t command, uint8_t *bufPtr, const int bufSize); - bool FilterCommand(uint8_t *bufCmdIn, uint32_t *idOut, uint8_t **pContentBuf); - void *AdminContext(const uint8_t op, const uint32_t id, HCtxForward hInput); - bool DoForwardBegin(HCtxForward ctx); - int SendForwardBuf(HCtxForward ctx, uint8_t *bufPtr, const int size); - bool CheckNodeInfo(const char *nodeInfo, string as[2]); - void FreeContext(HCtxForward ctxIn, const uint32_t id, bool bNotifyRemote); - int LoopFdRead(HCtxForward ctx); - void FreeContextCallBack(HCtxForward ctx); - void FreeJDWP(HCtxForward ctx); - void OnAccept(uv_stream_t *server, HCtxForward ctxClient, uv_stream_t *client); - bool DetechForwardType(HCtxForward ctxPoint); - bool SetupTCPPoint(HCtxForward ctxPoint); - bool SetupDevicePoint(HCtxForward ctxPoint); - bool SetupFilePoint(HCtxForward ctxPoint); - bool ForwardCommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); - bool CommandForwardCheckResult(HCtxForward ctx, uint8_t *payload); - bool LocalAbstractConnect(uv_pipe_t *pipe, string &sNodeCfg); - - map mapCtxPoint; - string taskCommand; - const uint8_t FORWARD_PARAMENTER_BUFSIZE = 8; - const string FILESYSTEM_SOCKET_PREFIX = "/tmp/"; - const string HARMONY_RESERVED_SOCKET_PREFIX = "/dev/socket/"; - // set true to enable slave check when forward create - const bool slaveCheckWhenBegin = false; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/common/serial_struct.h b/services/flashd/common/serial_struct.h deleted file mode 100755 index b151f9dc..00000000 --- a/services/flashd/common/serial_struct.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_SERIAL_STRUCT_H -#define HDC_SERIAL_STRUCT_H -#include "common.h" -#include "serial_struct_define.h" -#include "transfer.h" - -namespace Hdc { -namespace SerialStruct { - constexpr int fieldOne = 1; - constexpr int fieldTwo = 2; - constexpr int fieldThree = 3; - constexpr int fieldFour = 4; - constexpr int fieldFive = 5; - constexpr int fieldSix = 6; - constexpr int fieldSeven = 7; - constexpr int fieldEight = 8; - constexpr int fieldNine = 9; - constexpr int fieldTen = 10; - constexpr int field11 = 11; - constexpr int field12 = 12; - constexpr int field13 = 13; - - template<> struct Descriptor { - static auto type() - { - return Message(Field("fileSize"), - Field("atime"), - Field("mtime"), - Field("options"), - Field("path"), - Field("optionalName"), - Field("updateIfNew"), - Field("compressType"), - Field("holdTimestamp"), - Field("functionName"), - Field("clientCwd"), - Field("reserve1"), - Field("reserve2")); - } - }; - - template<> struct Descriptor { - static auto type() - { - return Message(Field("index"), - Field("compressType"), - Field("compressSize"), - Field("uncompressSize")); - } - }; - - template<> struct Descriptor { - static auto type() - { - return Message(Field("banner"), - Field("authType"), - Field("sessionId"), - Field("connectKey"), - Field("buf")); - } - }; - - template<> struct Descriptor { - static auto type() - { - return Message(Field("channelId"), - Field("commandFlag"), - Field("checkSum"), - Field("vCode")); - } - }; -} // SerialStruct -} // Hdc -#endif // HDC_SERIAL_STRUCT_H diff --git a/services/flashd/common/serial_struct_define.h b/services/flashd/common/serial_struct_define.h deleted file mode 100755 index f2beb1cd..00000000 --- a/services/flashd/common/serial_struct_define.h +++ /dev/null @@ -1,1314 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_SERIAL_STRUCT_DEFINE_H -#define HDC_SERIAL_STRUCT_DEFINE_H -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// static file define. No need not modify. by zako -namespace Hdc { -// clang-format off -namespace SerialStruct { - namespace SerialDetail { - template struct MemPtr { - }; - template struct MemPtr { - using type = T; - using MemberType = U; - }; - template struct MessageImpl { - public: - MessageImpl(Fields &&... fields) - : _fields(std::move(fields)...) - { - } - - template void Visit(Handler &&handler) const - { - VisitImpl(std::forward(handler), std::make_index_sequence()); - } - - private: - std::tuple _fields; - - template void VisitImpl(Handler &&handler, std::index_sequence) const - { - (handler(std::get(_fields)), ...); - } - }; - - template struct FieldImpl { - using type = typename SerialDetail::MemPtr::type; - using MemberType = typename SerialDetail::MemPtr::MemberType; - constexpr static const uint32_t tag = Tag; - constexpr static const uint32_t flags = Flags; - const std::string field_name; - - static decltype(auto) get(const type &value) - { - return value.*MemPtr; - } - - static decltype(auto) get(type &value) - { - return value.*MemPtr; - } - }; - - template struct OneofFieldImpl { - using type = typename SerialDetail::MemPtr::type; - using MemberType = typename SerialDetail::MemPtr::MemberType; - constexpr static const uint32_t tag = Tag; - constexpr static const size_t index = Index; - constexpr static const uint32_t flags = Flags; - const std::string field_name; - - static decltype(auto) get(const type &value) - { - return value.*MemPtr; - } - - static decltype(auto) get(type &value) - { - return value.*MemPtr; - } - }; - - template - struct MapFieldImpl { - using type = typename SerialDetail::MemPtr::type; - using MemberType = typename SerialDetail::MemPtr::MemberType; - constexpr static const uint32_t tag = Tag; - constexpr static const uint32_t KEY_FLAGS = KeyFlags; - constexpr static const uint32_t VALUE_FLAGS = ValueFlags; - - const std::string field_name; - - static decltype(auto) get(const type &value) - { - return value.*MemPtr; - } - - static decltype(auto) get(type &value) - { - return value.*MemPtr; - } - }; - } - - enum class WireType : uint32_t { - VARINT = 0, - FIXED64 = 1, - LENGTH_DELIMETED = 2, - START_GROUP = 3, - END_GROUP = 4, - FIXED32 = 5, - }; - enum flags { no = 0, s = 1, f = 2 }; - template struct FlagsType { - }; - - template struct Descriptor { - static_assert(sizeof(T) == 0, "You need to implement descriptor for your own types"); - static void type() - { - } - }; - - template constexpr auto Message(Fields &&... fields) - { - return SerialDetail::MessageImpl(std::forward(fields)...); - } - - template constexpr auto Field(const std::string &fieldName) - { - return SerialDetail::FieldImpl { fieldName }; - } - - template - constexpr auto OneofField(const std::string &fieldName) - { - return SerialDetail::OneofFieldImpl { fieldName }; - } - - template - constexpr auto MapField(const std::string &fieldName) - { - return SerialDetail::MapFieldImpl { fieldName }; - } - - template const auto &MessageType() - { - static const auto message = Descriptor::type(); - return message; - } - - template struct Serializer; - - struct Writer { - virtual void Write(const void *bytes, size_t size) = 0; - }; - - struct reader { - virtual size_t Read(void *bytes, size_t size) = 0; - }; - - namespace SerialDetail { - template - struct HasSerializePacked : public std::false_type { - }; - - template - struct HasSerializePacked().SerializePacked( - std::declval(), std::declval(), std::declval()))>> : public std::true_type { - }; - - template - constexpr bool HAS_SERIALIZE_PACKED_V = HasSerializePacked::value; - - template - struct HasParsePacked : public std::false_type { - }; - - template - struct HasParsePacked().ParsePacked( - std::declval(), std::declval(), std::declval()))>> : public std::true_type { - }; - - template - constexpr bool HAS_PARSE_PACKED_V = HasParsePacked::value; - - static uint32_t MakeTagWireType(uint32_t tag, WireType wireType) - { - return (tag << 3) | static_cast(wireType); - } - - static inline void ReadTagWireType(uint32_t tagKey, uint32_t &tag, WireType &wireType) - { - wireType = static_cast(tagKey & 0b0111); - tag = tagKey >> 3; - } - - static uint32_t MakeZigzagValue(int32_t value) - { - return (static_cast(value) << 1) ^ static_cast(value >> 31); - } - - static uint64_t MakeZigzagValue(int64_t value) - { - return (static_cast(value) << 1) ^ static_cast(value >> 63); - } - - static int32_t ReadZigzagValue(uint32_t value) - { - return static_cast((value >> 1) ^ (~(value & 1) + 1)); - } - - static int64_t ReadZigzagValue(uint64_t value) - { - return static_cast((value >> 1) ^ (~(value & 1) + 1)); - } - - template To BitCast(From from) - { - static_assert(sizeof(To) == sizeof(From), ""); - static_assert(std::is_trivially_copyable_v, ""); - static_assert(std::is_trivially_copyable_v, ""); - To to; - memcpy_s(&to, sizeof(To), &from, sizeof(from)); - return to; - } - - struct WriterSizeCollector : public Writer { - void Write(const void *, size_t size) override - { - byte_size += size; - } - size_t byte_size = 0; - }; - - struct LimitedReader : public reader { - LimitedReader(reader &parent, size_t sizeLimit) - : _parent(parent), _size_limit(sizeLimit) - { - } - - size_t Read(void *bytes, size_t size) - { - auto sizeToRead = std::min(size, _size_limit); - auto readSize = _parent.Read(bytes, sizeToRead); - _size_limit -= readSize; - return readSize; - } - - size_t AvailableBytes() const - { - return _size_limit; - } - - private: - reader &_parent; - size_t _size_limit; - }; - - static bool ReadByte(uint8_t &value, reader &in) - { - return in.Read(&value, 1) == 1; - } - - static void WriteVarint(uint32_t value, Writer &out) - { - uint8_t b[5] {}; - for (size_t i = 0; i < 5; ++i) { - b[i] = value & 0b0111'1111; - value >>= 7; - if (value) { - b[i] |= 0b1000'0000; - } else { - out.Write(b, i + 1); - break; - } - } - } - - static void WriteVarint(uint64_t value, Writer &out) - { - uint8_t b[10] {}; - for (size_t i = 0; i < 10; ++i) { - b[i] = value & 0b0111'1111; - value >>= 7; - if (value) { - b[i] |= 0b1000'0000; - } else { - out.Write(b, i + 1); - break; - } - } - } - -#if defined(HOST_MAC) - static void WriteVarint(unsigned long value, Writer &out) - { - WriteVarint(static_cast(value), out); - } -#endif - - static bool ReadVarint(uint32_t &value, reader &in) - { - value = 0; - for (size_t c = 0; c < 5; ++c) { - uint8_t x; - if (!ReadByte(x, in)) { - return false; - } - value |= static_cast(x & 0b0111'1111) << 7 * c; - if (!(x & 0b1000'0000)) { - return true; - } - } - - return false; - } - - static bool ReadVarint(uint64_t &value, reader &in) - { - value &= 0; - for (size_t c = 0; c < 10; ++c) { - uint8_t x; - if (!ReadByte(x, in)) { - return false; - } - value |= static_cast(x & 0b0111'1111) << 7 * c; - if (!(x & 0b1000'0000)) { - return true; - } - } - return false; - } - -#if defined(HOST_MAC) - static bool ReadVarint(unsigned long &value, reader &in) - { - uint64_t intermediateValue; - if (ReadVarint(intermediateValue, in)) { - value = static_cast(intermediateValue); - return true; - } - return false; - } -#endif - - static void WriteFixed(uint32_t value, Writer &out) - { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - out.Write(&value, sizeof(value)); -#else - static_assert(false, "Not a little-endian"); -#endif - } - - static void WriteFixed(uint64_t value, Writer &out) - { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - out.Write(&value, sizeof(value)); -#else - static_assert(false, "Not a little-endian"); -#endif - } - - static void WriteFixed(double value, Writer &out) - { - WriteFixed(BitCast(value), out); - } - - static void WriteFixed(float value, Writer &out) - { - WriteFixed(BitCast(value), out); - } - - static void WriteVarint(int32_t value, Writer &out) - { - WriteVarint(BitCast(value), out); - } - - static void WriteVarint(int64_t value, Writer &out) - { - WriteVarint(BitCast(value), out); - } - - static void WriteSignedVarint(int32_t value, Writer &out) - { - WriteVarint(MakeZigzagValue(value), out); - } - - static void WriteSignedVarint(int64_t value, Writer &out) - { - WriteVarint(MakeZigzagValue(value), out); - } - - static void WriteSignedFixed(int32_t value, Writer &out) - { - WriteFixed(static_cast(value), out); - } - - static void WriteSignedFixed(int64_t value, Writer &out) - { - WriteFixed(static_cast(value), out); - } - - static void WriteTagWriteType(uint32_t tag, WireType wireType, Writer &out) - { - WriteVarint(MakeTagWireType(tag, wireType), out); - } - - static bool ReadFixed(uint32_t &value, reader &in) - { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return in.Read(&value, sizeof(value)) == sizeof(value); -#else - static_assert(false, "Not a little-endian"); -#endif - } - - static bool ReadFixed(uint64_t &value, reader &in) - { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return in.Read(&value, sizeof(value)) == sizeof(value); -#else - static_assert(false, "Not a little-endian"); -#endif - } - - static bool ReadFixed(double &value, reader &in) - { - uint64_t intermediateValue; - if (ReadFixed(intermediateValue, in)) { - value = BitCast(intermediateValue); - return true; - } - return false; - } - - static bool ReadFixed(float &value, reader &in) - { - uint32_t intermediateValue; - if (ReadFixed(intermediateValue, in)) { - value = BitCast(intermediateValue); - return true; - } - return false; - } - - static bool ReadVarint(int32_t &value, reader &in) - { - uint32_t intermediateValue; - if (ReadVarint(intermediateValue, in)) { - value = BitCast(intermediateValue); - return true; - } - return false; - } - - static bool ReadVarint(int64_t &value, reader &in) - { - uint64_t intermediateValue; - if (ReadVarint(intermediateValue, in)) { - value = BitCast(intermediateValue); - return true; - } - return false; - } - - static bool ReadSignedVarint(int32_t &value, reader &in) - { - uint32_t intermediateValue; - if (ReadVarint(intermediateValue, in)) { - value = ReadZigzagValue(intermediateValue); - return true; - } - return false; - } - - static bool ReadSignedVarint(int64_t &value, reader &in) - { - uint64_t intermediateValue; - if (ReadVarint(intermediateValue, in)) { - value = ReadZigzagValue(intermediateValue); - return true; - } - return false; - } - - static bool ReadSignedFixed(int32_t &value, reader &in) - { - uint32_t intermediateValue; - if (ReadFixed(intermediateValue, in)) { - value = static_cast(intermediateValue); - return true; - } - return false; - } - - static bool ReadSignedFixed(int64_t &value, reader &in) - { - uint64_t intermediateValue; - if (ReadFixed(intermediateValue, in)) { - value = static_cast(intermediateValue); - return true; - } - return false; - } - - template - void WriteField(const T &value, - const SerialDetail::OneofFieldImpl &, Writer &out) - { - using OneOf = SerialDetail::OneofFieldImpl; - Serializer::template SerializeOneof( - OneOf::tag, OneOf::get(value), FlagsType(), out); - } - - template - void WriteField(const T &value, - const SerialDetail::MapFieldImpl &, Writer &out) - { - using Map = SerialDetail::MapFieldImpl; - Serializer::SerializeMap( - Map::tag, Map::get(value), FlagsType(), FlagsType(), out); - } - - template - void WriteField(const T &value, const SerialDetail::FieldImpl &, Writer &out) - { - using Field = SerialDetail::FieldImpl; - Serializer::Serialize( - Field::tag, Field::get(value), FlagsType(), out); - } - - template - void WriteMessage(const T &value, const SerialDetail::MessageImpl &message, Writer &out) - { - message.Visit([&](const auto &field) { WriteField(value, field, out); }); - } - - template - void WriteRepeated(uint32_t tag, It begin, It end, Writer &out) - { - if (begin == end) { - return; - } - if constexpr (SerialDetail::HAS_SERIALIZE_PACKED_V, ValueType, FlagsType, - Writer>) { - WriteVarint(MakeTagWireType(tag, WireType::LENGTH_DELIMETED), out); - WriterSizeCollector sizeCollector; - for (auto it = begin; it != end; ++it) { - Serializer::SerializePacked(*it, FlagsType {}, sizeCollector); - } - WriteVarint(sizeCollector.byte_size, out); - for (auto it = begin; it != end; ++it) { - Serializer::SerializePacked(*it, FlagsType {}, out); - } - } else { - for (auto it = begin; it != end; ++it) { - Serializer::Serialize(tag, *it, FlagsType(), out); - } - } - } - - template - void WriteMapKeyValue(const std::pair &value, Writer &out) - { - Serializer::Serialize(1, value.first, FlagsType {}, out, true); - Serializer::Serialize(2, value.second, FlagsType {}, out, true); - } - - template - void WriteMap(uint32_t tag, const T &value, Writer &out) - { - auto begin = std::begin(value); - auto end = std::end(value); - - for (auto it = begin; it != end; ++it) { - WriteTagWriteType(tag, WireType::LENGTH_DELIMETED, out); - WriterSizeCollector sizeCollector; - WriteMapKeyValue(*it, sizeCollector); - WriteVarint(sizeCollector.byte_size, out); - WriteMapKeyValue(*it, out); - } - } - - template - bool ReadMapKeyValue(std::pair &value, reader &in) - { - static const auto pairAsMessage = Message(Field<1, &std::pair::first, KeyFlags>("key"), - Field<2, &std::pair::second, ValueFlags>("value")); - return ReadMessage(value, pairAsMessage, in); - } - - template - bool ReadMap(WireType wireType, T &value, reader &in) - { - if (wireType != WireType::LENGTH_DELIMETED) { - return false; - } - size_t size; - if (ReadVarint(size, in)) { - LimitedReader limitedIn(in, size); - while (limitedIn.AvailableBytes() > 0) { - std::pair item; - if (!ReadMapKeyValue(item, limitedIn)) { - return false; - } - value.insert(std::move(item)); - } - return true; - } - return false; - } - - template - bool ReadRepeated(WireType wireType, OutputIt output_it, reader &in) - { - if constexpr (SerialDetail::HAS_PARSE_PACKED_V, ValueType, FlagsType, - reader>) { - if (wireType != WireType::LENGTH_DELIMETED) { - return false; - } - - size_t size; - if (ReadVarint(size, in)) { - LimitedReader limitedIn(in, size); - - while (limitedIn.AvailableBytes() > 0) { - ValueType value; - if (!Serializer::ParsePacked(value, FlagsType(), limitedIn)) { - return false; - } - output_it = value; - ++output_it; - } - return true; - } - return false; - } else { - ValueType value; - if (Serializer::Parse(wireType, value, FlagsType(), in)) { - output_it = value; - ++output_it; - return true; - } - return false; - } - } - - template - void ReadField(T &value, uint32_t tag, WireType wireType, - const SerialDetail::OneofFieldImpl &, reader &in) - { - if (Tag != tag) { - return; - } - using OneOf = SerialDetail::OneofFieldImpl; - Serializer::template ParseOneof( - wireType, OneOf::get(value), FlagsType(), in); - } - - template - void ReadField(T &value, uint32_t tag, WireType wireType, - const SerialDetail::MapFieldImpl &, reader &in) - { - if (Tag != tag) { - return; - } - using Map = SerialDetail::MapFieldImpl; - Serializer::ParseMap( - wireType, Map::get(value), FlagsType(), FlagsType(), in); - } - - template - void ReadField(T &value, uint32_t tag, WireType wireType, - const SerialDetail::FieldImpl &, reader &in) - { - if (Tag != tag) { - return; - } - using Field = SerialDetail::FieldImpl; - Serializer::Parse(wireType, Field::get(value), FlagsType(), in); - } - - template bool ReadMessage(T &value, const MessageImpl &message, reader &in) - { - uint32_t tagKey; - while (ReadVarint(tagKey, in)) { - uint32_t tag; - WireType wireType; - ReadTagWireType(tagKey, tag, wireType); - message.Visit([&](const auto &field) { ReadField(value, tag, wireType, field, in); }); - } - return true; - } - } - - template struct Serializer { - // Commion Serializer threat type as Message - static void Serialize(uint32_t tag, const T &value, FlagsType<>, Writer &out, bool force = false) - { - SerialDetail::WriterSizeCollector sizeCollector; - SerialDetail::WriteMessage(value, MessageType(), sizeCollector); - if (!force && sizeCollector.byte_size == 0) { - return; - } - SerialDetail::WriteTagWriteType(tag, WireType::LENGTH_DELIMETED, out); - SerialDetail::WriteVarint(sizeCollector.byte_size, out); - SerialDetail::WriteMessage(value, MessageType(), out); - } - - static bool Parse(WireType wireType, T &value, FlagsType<>, reader &in) - { - if (wireType != WireType::LENGTH_DELIMETED) { - return false; - } - size_t size; - if (SerialDetail::ReadVarint(size, in)) { - SerialDetail::LimitedReader limitedIn(in, size); - return SerialDetail::ReadMessage(value, MessageType(), limitedIn); - } - return false; - } - }; - - template<> struct Serializer { - static void Serialize(uint32_t tag, int32_t value, FlagsType<>, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); - SerialDetail::WriteVarint(value, out); - } - - static void Serialize(uint32_t tag, int32_t value, FlagsType, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); - SerialDetail::WriteSignedVarint(value, out); - } - - static void Serialize( - uint32_t tag, int32_t value, FlagsType, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::FIXED32, out); - SerialDetail::WriteSignedFixed(value, out); - } - - static void SerializePacked(int32_t value, FlagsType<>, Writer &out) - { - SerialDetail::WriteVarint(value, out); - } - - static void SerializePacked(int32_t value, FlagsType, Writer &out) - { - SerialDetail::WriteSignedVarint(value, out); - } - - static void SerializePacked(int32_t value, FlagsType, Writer &out) - { - SerialDetail::WriteSignedFixed(value, out); - } - - static bool Parse(WireType wire_type, int32_t &value, FlagsType<>, reader &in) - { - if (wire_type != WireType::VARINT) - return false; - return SerialDetail::ReadVarint(value, in); - } - - static bool Parse(WireType wire_type, int32_t &value, FlagsType, reader &in) - { - if (wire_type != WireType::VARINT) - return false; - return SerialDetail::ReadSignedVarint(value, in); - } - - static bool Parse(WireType wire_type, int32_t &value, FlagsType, reader &in) - { - if (wire_type != WireType::FIXED32) - return false; - return SerialDetail::ReadSignedFixed(value, in); - } - - static bool ParsePacked(int32_t &value, FlagsType<>, reader &in) - { - return SerialDetail::ReadVarint(value, in); - } - - static bool ParsePacked(int32_t &value, FlagsType, reader &in) - { - return SerialDetail::ReadSignedVarint(value, in); - } - - static bool ParsePacked(int32_t &value, FlagsType, reader &in) - { - return SerialDetail::ReadSignedFixed(value, in); - } - }; - - template<> struct Serializer { - static void Serialize(uint32_t tag, uint32_t value, FlagsType<>, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); - SerialDetail::WriteVarint(value, out); - } - - static void Serialize(uint32_t tag, uint32_t value, FlagsType, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::FIXED32, out); - SerialDetail::WriteFixed(value, out); - } - - static void SerializePacked(uint32_t value, FlagsType<>, Writer &out) - { - SerialDetail::WriteVarint(value, out); - } - - static void SerializePacked(uint32_t value, FlagsType, Writer &out) - { - SerialDetail::WriteFixed(value, out); - } - - static bool Parse(WireType wire_type, uint32_t &value, FlagsType<>, reader &in) - { - if (wire_type != WireType::VARINT) - return false; - return SerialDetail::ReadVarint(value, in); - } - - static bool Parse(WireType wire_type, uint32_t &value, FlagsType, reader &in) - { - if (wire_type != WireType::FIXED32) - return false; - return SerialDetail::ReadFixed(value, in); - } - - static bool ParsePacked(uint32_t &value, FlagsType<>, reader &in) - { - return SerialDetail::ReadVarint(value, in); - } - - static bool ParsePacked(uint32_t &value, FlagsType, reader &in) - { - return SerialDetail::ReadFixed(value, in); - } - }; - - template<> struct Serializer { - static void Serialize(uint32_t tag, int64_t value, FlagsType<>, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); - SerialDetail::WriteVarint(value, out); - } - - static void Serialize(uint32_t tag, int64_t value, FlagsType, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); - SerialDetail::WriteSignedVarint(value, out); - } - - static void Serialize( - uint32_t tag, int64_t value, FlagsType, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::FIXED64, out); - SerialDetail::WriteSignedFixed(value, out); - } - - static void SerializePacked(int64_t value, FlagsType<>, Writer &out) - { - SerialDetail::WriteVarint(value, out); - } - - static void SerializePacked(int64_t value, FlagsType, Writer &out) - { - SerialDetail::WriteSignedVarint(value, out); - } - - static void SerializePacked(int64_t value, FlagsType, Writer &out) - { - SerialDetail::WriteSignedFixed(value, out); - } - - static bool Parse(WireType wire_type, int64_t &value, FlagsType<>, reader &in) - { - if (wire_type != WireType::VARINT) - return false; - return SerialDetail::ReadVarint(value, in); - } - - static bool Parse(WireType wire_type, int64_t &value, FlagsType, reader &in) - { - if (wire_type != WireType::VARINT) - return false; - return SerialDetail::ReadSignedVarint(value, in); - } - - static bool Parse(WireType wire_type, int64_t &value, FlagsType, reader &in) - { - if (wire_type != WireType::FIXED64) - return false; - return SerialDetail::ReadSignedFixed(value, in); - } - - static bool ParsePacked(int64_t &value, FlagsType<>, reader &in) - { - return SerialDetail::ReadVarint(value, in); - } - - static bool ParsePacked(int64_t &value, FlagsType, reader &in) - { - return SerialDetail::ReadSignedVarint(value, in); - } - - static bool ParsePacked(int64_t &value, FlagsType, reader &in) - { - return SerialDetail::ReadSignedFixed(value, in); - } - }; - - template<> struct Serializer { - static void Serialize(uint32_t tag, uint64_t value, FlagsType<>, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out); - SerialDetail::WriteVarint(value, out); - } - - static void Serialize(uint32_t tag, uint64_t value, FlagsType, Writer &out, bool force = false) - { - if (!force && value == UINT64_C(0)) - return; - - SerialDetail::WriteTagWriteType(tag, WireType::FIXED64, out); - SerialDetail::WriteFixed(value, out); - } - - static void SerializePacked(uint64_t value, FlagsType<>, Writer &out) - { - SerialDetail::WriteVarint(value, out); - } - - static void SerializePacked(uint64_t value, FlagsType, Writer &out) - { - SerialDetail::WriteFixed(value, out); - } - - static bool Parse(WireType wire_type, uint64_t &value, FlagsType<>, reader &in) - { - if (wire_type != WireType::VARINT) - return false; - return SerialDetail::ReadVarint(value, in); - } - - static bool Parse(WireType wire_type, uint64_t &value, FlagsType, reader &in) - { - if (wire_type != WireType::FIXED64) - return false; - return SerialDetail::ReadFixed(value, in); - } - - static bool ParsePacked(uint64_t &value, FlagsType<>, reader &in) - { - return SerialDetail::ReadVarint(value, in); - } - - static bool ParsePacked(uint64_t &value, FlagsType, reader &in) - { - return SerialDetail::ReadFixed(value, in); - } - }; - - template<> struct Serializer { - static void Serialize(uint32_t tag, double value, FlagsType<>, Writer &out, bool force = false) - { - if (!force && std::fpclassify(value) == FP_ZERO) { - return; - } - SerialDetail::WriteTagWriteType(tag, WireType::FIXED64, out); - SerialDetail::WriteFixed(value, out); - } - - static void SerializePacked(double value, FlagsType<>, Writer &out) - { - SerialDetail::WriteFixed(value, out); - } - - static bool Parse(WireType wire_type, double &value, FlagsType<>, reader &in) - { - if (wire_type != WireType::FIXED64) { - return false; - } - return SerialDetail::ReadFixed(value, in); - } - - static bool ParsePacked(double &value, FlagsType<>, reader &in) - { - return SerialDetail::ReadFixed(value, in); - } - }; - - template<> struct Serializer { - static void Serialize(uint32_t tag, float value, FlagsType<>, Writer &out, bool force = false) - { - if (!force && std::fpclassify(value) == FP_ZERO) { - return; - } - SerialDetail::WriteTagWriteType(tag, WireType::FIXED32, out); - SerialDetail::WriteFixed(value, out); - } - - static void SerializePacked(float value, FlagsType<>, Writer &out) - { - SerialDetail::WriteFixed(value, out); - } - - static bool Parse(WireType wire_type, float &value, FlagsType<>, reader &in) - { - if (wire_type != WireType::FIXED32) { - return false; - } - return SerialDetail::ReadFixed(value, in); - } - - static bool ParsePacked(float &value, FlagsType<>, reader &in) - { - return SerialDetail::ReadFixed(value, in); - } - }; - - template<> struct Serializer { - static void Serialize(uint32_t tag, bool value, FlagsType<>, Writer &out, bool force = false) - { - Serializer::Serialize(tag, value ? 1 : 0, FlagsType(), out, force); - } - - static void SerializePacked(bool value, FlagsType<>, Writer &out) - { - Serializer::SerializePacked(value ? 1 : 0, FlagsType(), out); - } - - static bool Parse(WireType wire_type, bool &value, FlagsType<>, reader &in) - { - uint32_t intermedaite_value; - if (Serializer::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) { - value = static_cast(intermedaite_value); - return true; - } - return false; - } - - static bool ParsePacked(bool &value, FlagsType<>, reader &in) - { - uint32_t intermedaite_value; - if (Serializer::ParsePacked(intermedaite_value, FlagsType<>(), in)) { - value = static_cast(intermedaite_value); - return true; - } - return false; - } - }; - - template struct Serializer>> { - using U = std::underlying_type_t; - - static void Serialize(uint32_t tag, T value, FlagsType<>, Writer &out, bool force = false) - { - Serializer::Serialize(tag, static_cast(value), FlagsType<>(), out, force); - } - - static void SerializePacked(T value, FlagsType<>, Writer &out) - { - Serializer::SerializePacked(static_cast(value), FlagsType<>(), out); - } - - static bool Parse(WireType wire_type, T &value, FlagsType<>, reader &in) - { - U intermedaite_value; - if (Serializer::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) { - value = static_cast(intermedaite_value); - return true; - } - return false; - } - - static bool ParsePacked(T &value, FlagsType<>, reader &in) - { - U intermedaite_value; - if (Serializer::ParsePacked(intermedaite_value, FlagsType<>(), in)) { - value = static_cast(intermedaite_value); - return true; - } - return false; - } - }; - - template<> struct Serializer { - static void Serialize(uint32_t tag, const std::string &value, FlagsType<>, Writer &out, bool force = false) - { - SerialDetail::WriteTagWriteType(tag, WireType::LENGTH_DELIMETED, out); - SerialDetail::WriteVarint(value.size(), out); - out.Write(value.data(), value.size()); - } - - static bool Parse(WireType wire_type, std::string &value, FlagsType<>, reader &in) - { - if (wire_type != WireType::LENGTH_DELIMETED) { - return false; - } - size_t size; - if (SerialDetail::ReadVarint(size, in)) { - value.resize(size); - if (in.Read(value.data(), size) == size) { - return true; - } - } - return false; - } - }; - - template struct Serializer> { - template - static void Serialize(uint32_t tag, const std::vector &value, FlagsType, Writer &out) - { - SerialDetail::WriteRepeated(tag, value.begin(), value.end(), out); - } - - template - static bool Parse(WireType wire_type, std::vector &value, FlagsType, reader &in) - { - return SerialDetail::ReadRepeated(wire_type, std::back_inserter(value), in); - } - }; - - template struct Serializer> { - template - static void Serialize(uint32_t tag, const std::optional &value, FlagsType, Writer &out) - { - if (!value.has_value()) { - return; - } - Serializer::Serialize(tag, *value, FlagsType(), out); - } - - template - static bool Parse(WireType wire_type, std::optional &value, FlagsType, reader &in) - { - return Serializer::Parse(wire_type, value.emplace(), FlagsType(), in); - } - }; - - template struct Serializer> { - template - static void SerializeOneof(uint32_t tag, const std::variant &value, FlagsType, Writer &out) - { - if (value.index() != Index) - return; - - Serializer>>::Serialize( - tag, std::get(value), FlagsType(), out); - } - - template - static bool ParseOneof(WireType wire_type, std::variant &value, FlagsType, reader &in) - { - return Serializer>>::Parse( - wire_type, value.template emplace(), FlagsType(), in); - } - }; - - template struct Serializer> { - template - static void SerializeMap( - uint32_t tag, const std::map &value, FlagsType, FlagsType, Writer &out) - { - SerialDetail::WriteMap(tag, value, out); - } - - template - static bool ParseMap( - WireType wire_type, std::map &value, FlagsType, FlagsType, reader &in) - { - return SerialDetail::ReadMap(wire_type, value, in); - } - }; - - struct StringWriter : public Writer { - StringWriter(std::string &out) - : _out(out) - { - } - - void Write(const void *bytes, size_t size) override - { - _out.append(reinterpret_cast(bytes), size); - } - - private: - std::string &_out; - }; - - struct StringReader : public reader { - StringReader(const std::string &in) - : _in(in), _pos(0) - { - } - - size_t Read(void *bytes, size_t size) override - { - size_t readSize = std::min(size, _in.size() - _pos); - if (memcpy_s(bytes, size, _in.data() + _pos, readSize) != EOK) { - return readSize; - } - _pos += readSize; - return readSize; - } - - private: - const std::string &_in; - size_t _pos; - }; - // mytype begin, just support base type, but really use protobuf raw type(uint32) - template<> struct Serializer { - static void Serialize(uint32_t tag, uint8_t value, FlagsType<>, Writer &out, bool force = false) - { - Serializer::Serialize(tag, value, FlagsType(), out, force); - } - - static void SerializePacked(uint8_t value, FlagsType<>, Writer &out) - { - Serializer::SerializePacked(value, FlagsType(), out); - } - - static bool Parse(WireType wire_type, uint8_t &value, FlagsType<>, reader &in) - { - uint32_t intermedaite_value; - if (Serializer::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) { - value = static_cast(intermedaite_value); - return true; - } - return false; - } - - static bool ParsePacked(uint8_t &value, FlagsType<>, reader &in) - { - uint32_t intermedaite_value; - if (Serializer::ParsePacked(intermedaite_value, FlagsType<>(), in)) { - value = static_cast(intermedaite_value); - return true; - } - return false; - } - }; - template<> struct Serializer { - static void Serialize(uint32_t tag, uint16_t value, FlagsType<>, Writer &out, bool force = false) - { - Serializer::Serialize(tag, value, FlagsType(), out, force); - } - - static void SerializePacked(uint16_t value, FlagsType<>, Writer &out) - { - Serializer::SerializePacked(value, FlagsType(), out); - } - - static bool Parse(WireType wire_type, uint16_t &value, FlagsType<>, reader &in) - { - uint32_t intermedaite_value; - if (Serializer::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) { - value = static_cast(intermedaite_value); - return true; - } - return false; - } - - static bool ParsePacked(uint16_t &value, FlagsType<>, reader &in) - { - uint32_t intermedaite_value; - if (Serializer::ParsePacked(intermedaite_value, FlagsType<>(), in)) { - value = static_cast(intermedaite_value); - return true; - } - return false; - } - }; - // mytype finish - - template std::string SerializeToString(const T &value) - { - std::string out; - StringWriter stringOut(out); - SerialDetail::WriteMessage(value, MessageType(), stringOut); - return out; - } - - template bool ParseFromString(T &value, const std::string &in) - { - StringReader stringIn(in); - return SerialDetail::ReadMessage(value, MessageType(), stringIn); - } -} -// clang-format on -} // Hdc -#endif // HDC_SERIAL_STRUCT_DEFINE_H diff --git a/services/flashd/common/session.cpp b/services/flashd/common/session.cpp deleted file mode 100755 index bef648a2..00000000 --- a/services/flashd/common/session.cpp +++ /dev/null @@ -1,1062 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "session.h" -#include "serial_struct.h" - -namespace Hdc { -HdcSessionBase::HdcSessionBase(bool serverOrDaemonIn) -{ - // server/daemon common initialization code - string threadNum = std::to_string(SIZE_THREAD_POOL); - uv_os_setenv("UV_THREADPOOL_SIZE", threadNum.c_str()); - uv_loop_init(&loopMain); - WRITE_LOG(LOG_DEBUG, "loopMain init"); - uv_rwlock_init(&mainAsync); - uv_async_init(&loopMain, &asyncMainLoop, MainAsyncCallback); - uv_rwlock_init(&lockMapSession); - serverOrDaemon = serverOrDaemonIn; - ctxUSB = nullptr; - wantRestart = false; - -#ifdef HDC_HOST - if (serverOrDaemon) { - libusb_init((libusb_context **)&ctxUSB); - } -#endif -} - -HdcSessionBase::~HdcSessionBase() -{ - Base::TryCloseHandle((uv_handle_t *)&asyncMainLoop); - uv_loop_close(&loopMain); - // clear base - uv_rwlock_destroy(&mainAsync); - uv_rwlock_destroy(&lockMapSession); -#ifdef HDC_HOST - if (serverOrDaemon) { - libusb_exit((libusb_context *)ctxUSB); - } -#endif - WRITE_LOG(LOG_DEBUG, "~HdcSessionBase free sessionRef:%d instance:%s", uint32_t(sessionRef), - serverOrDaemon ? "server" : "daemon"); -} - -// remove step2 -bool HdcSessionBase::TryRemoveTask(HTaskInfo hTask) -{ - if (hTask->taskFree) { - return true; - } - bool ret = RemoveInstanceTask(OP_REMOVE, hTask); - if (ret) { - hTask->taskFree = true; - } else { - // This is used to check that the memory cannot be cleaned up. If the memory cannot be released, break point - // here to see which task has not been released - // print task clear - } - return ret; -} - -// remove step1 -bool HdcSessionBase::BeginRemoveTask(HTaskInfo hTask) -{ - bool ret = true; - if (hTask->taskStop || hTask->taskFree || !hTask->taskClass) { - return true; - } - - WRITE_LOG(LOG_DEBUG, "BeginRemoveTask taskType:%d", hTask->taskType); - ret = RemoveInstanceTask(OP_CLEAR, hTask); - auto taskClassDeleteRetry = [](uv_idle_t *handle) -> void { - HTaskInfo hTask = (HTaskInfo)handle->data; - HdcSessionBase *thisClass = (HdcSessionBase *)hTask->ownerSessionClass; - if (!thisClass->TryRemoveTask(hTask)) { - return; - } - HSession hSession = thisClass->AdminSession(OP_QUERY, hTask->sessionId, nullptr); - thisClass->AdminTask(OP_REMOVE, hSession, hTask->channelId, nullptr); - WRITE_LOG(LOG_DEBUG, "TaskDelay task remove finish, channelId:%d", hTask->channelId); - delete hTask; - Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseIdleCallback); - }; - Base::IdleUvTask(hTask->runLoop, hTask, taskClassDeleteRetry); - - hTask->taskStop = true; - ret = true; - return ret; -} - -// Clear all Task or a single Task, the regular situation is stopped first, and the specific class memory is cleaned up -// after the end of the LOOP. -// When ChannelIdinput == 0, at this time, all of the LOOP ends, all runs in the class end, so directly skip STOP, -// physical memory deletion class trimming -void HdcSessionBase::ClearOwnTasks(HSession hSession, const uint32_t channelIDInput) -{ - // First case: normal task cleanup process (STOP Remove) - // Second: The task is cleaned up, the session ends - // Third: The task is cleaned up, and the session is directly over the session. - map::iterator iter; - for (iter = hSession->mapTask->begin(); iter != hSession->mapTask->end();) { - uint32_t channelId = iter->first; - HTaskInfo hTask = iter->second; - if (channelIDInput != 0) { // single - if (channelIDInput != channelId) { - ++iter; - continue; - } - BeginRemoveTask(hTask); - WRITE_LOG(LOG_DEBUG, "ClearOwnTasks OP_CLEAR finish,session:%p channelIDInput:%d", hSession, - channelIDInput); - break; - } - // multi - BeginRemoveTask(hTask); - ++iter; - } -} - -void HdcSessionBase::ClearSessions() -{ - // no need to lock mapSession - // broadcast free singal - for (auto v : mapSession) { - HSession hSession = (HSession)v.second; - if (!hSession->isDead) { - FreeSession(hSession->sessionId); - } - } -} - -void HdcSessionBase::ReMainLoopForInstanceClear() -{ // reloop - auto clearSessionsForFinish = [](uv_idle_t *handle) -> void { - HdcSessionBase *thisClass = (HdcSessionBase *)handle->data; - if (thisClass->sessionRef > 0) { - return; - } - // all task has been free - uv_close((uv_handle_t *)handle, Base::CloseIdleCallback); - uv_stop(&thisClass->loopMain); - }; - Base::IdleUvTask(&loopMain, this, clearSessionsForFinish); - uv_run(&loopMain, UV_RUN_DEFAULT); -}; - -void HdcSessionBase::EnumUSBDeviceRegister(void (*pCallBack)(HSession hSession)) -{ - if (!pCallBack) { - return; - } - uv_rwlock_rdlock(&lockMapSession); - map::iterator i; - for (i = mapSession.begin(); i != mapSession.end(); ++i) { - HSession hs = i->second; - if (hs->connType != CONN_USB) { - continue; - } - if (hs->hUSB == nullptr) { - continue; - } - if (pCallBack) { - pCallBack(hs); - } - break; - } - uv_rwlock_rdunlock(&lockMapSession); -} - -// The PC side gives the device information, determines if the USB device is registered -// PDEV and Busid Devid two choices -HSession HdcSessionBase::QueryUSBDeviceRegister(void *pDev, int busIDIn, int devIDIn) -{ -#ifdef HDC_HOST - libusb_device *dev = (libusb_device *)pDev; - HSession hResult = nullptr; - if (!mapSession.size()) { - return nullptr; - } - uint8_t busId = 0; - uint8_t devId = 0; - if (pDev) { - busId = libusb_get_bus_number(dev); - devId = libusb_get_device_address(dev); - } else { - busId = busIDIn; - devId = devIDIn; - } - uv_rwlock_rdlock(&lockMapSession); - map::iterator i; - for (i = mapSession.begin(); i != mapSession.end(); ++i) { - HSession hs = i->second; - if (hs->connType == CONN_USB) { - continue; - } - if (hs->hUSB == nullptr) { - continue; - } - if (hs->hUSB->devId != devId || hs->hUSB->busId != busId) { - continue; - } - hResult = hs; - break; - } - uv_rwlock_rdunlock(&lockMapSession); - return hResult; -#else - return nullptr; -#endif -} - -void HdcSessionBase::AsyncMainLoopTask(uv_idle_t *handle) -{ - AsyncParam *param = (AsyncParam *)handle->data; - HdcSessionBase *thisClass = (HdcSessionBase *)param->thisClass; - switch (param->method) { - case ASYNC_FREE_SESSION: - // Destruction is unified in the main thread - thisClass->FreeSession(param->sid); // todo Double lock - break; - case ASYNC_STOP_MAINLOOP: - uv_stop(&thisClass->loopMain); - break; - default: - break; - } - if (param->data) { - delete[]((uint8_t *)param->data); - } - delete param; - param = nullptr; - Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseIdleCallback); -} - -void HdcSessionBase::MainAsyncCallback(uv_async_t *handle) -{ - HdcSessionBase *thisClass = (HdcSessionBase *)handle->data; - list::iterator i; - list &lst = thisClass->lstMainThreadOP; - uv_rwlock_wrlock(&thisClass->mainAsync); - for (i = lst.begin(); i != lst.end();) { - AsyncParam *param = (AsyncParam *)*i; - Base::IdleUvTask(&thisClass->loopMain, param, AsyncMainLoopTask); - i = lst.erase(i); - } - uv_rwlock_wrunlock(&thisClass->mainAsync); -} - -void HdcSessionBase::PushAsyncMessage(const uint32_t sessionId, const uint8_t method, const void *data, - const int dataSize) -{ - AsyncParam *param = new AsyncParam(); - if (!param) { - return; - } - param->sid = sessionId; - param->thisClass = this; - param->method = method; - if (dataSize > 0) { - param->dataSize = dataSize; - param->data = new uint8_t[param->dataSize](); - if (!param->data) { - delete param; - return; - } - if (memcpy_s((uint8_t *)param->data, param->dataSize, data, dataSize)) { - delete[]((uint8_t *)param->data); - delete param; - return; - } - } - - asyncMainLoop.data = this; - uv_rwlock_wrlock(&mainAsync); - lstMainThreadOP.push_back(param); - uv_rwlock_wrunlock(&mainAsync); - uv_async_send(&asyncMainLoop); -} - -void HdcSessionBase::WorkerPendding() -{ - uv_run(&loopMain, UV_RUN_DEFAULT); - ClearInstanceResource(); -} - -int HdcSessionBase::MallocSessionByConnectType(HSession hSession) -{ - int ret = 0; - switch (hSession->connType) { - case CONN_TCP: { - uv_tcp_init(&loopMain, &hSession->hWorkTCP); - ++hSession->uvRef; - hSession->hWorkTCP.data = hSession; - break; - } - case CONN_USB: { - // Some members need to be placed at the primary thread - HUSB hUSB = new HdcUSB(); - if (!hUSB) { - ret = -1; - break; - } - hSession->hUSB = hUSB; -#ifdef HDC_HOST - constexpr auto maxBufFactor = 1.5; - int max = Base::GetMaxBufSize() * maxBufFactor + sizeof(USBHead); - hUSB->sizeEpBuf = max; - hUSB->bufDevice = new uint8_t[max](); - hUSB->bufHost = new uint8_t[max](); - hUSB->transferRecv = libusb_alloc_transfer(0); - hUSB->transferSend = libusb_alloc_transfer(0); -#else -#endif - break; - } - default: - ret = -1; - break; - } - return ret; -} - -// Avoid unit test when client\server\daemon on the same host, maybe get the same ID value -uint32_t HdcSessionBase::GetSessionPseudoUid() -{ - uint32_t uid = 0; - Hdc::HSession hInput = nullptr; - do { - uid = static_cast(Base::GetRandom()); - } while ((hInput = AdminSession(OP_QUERY, uid, nullptr)) != nullptr); - return uid; -} - -// when client 0 to automatic generated,when daemon First place 1 followed by -HSession HdcSessionBase::MallocSession(bool serverOrDaemon, const ConnType connType, void *classModule, - uint32_t sessionId) -{ - HSession hSession = new HdcSession(); - if (!hSession) { - return nullptr; - } - int ret = 0; - ++sessionRef; - memset_s(hSession->ctrlFd, sizeof(hSession->ctrlFd), 0, sizeof(hSession->ctrlFd)); - hSession->classInstance = this; - hSession->connType = connType; - hSession->classModule = classModule; - hSession->isDead = false; - hSession->sessionId = ((sessionId == 0) ? GetSessionPseudoUid() : sessionId); - hSession->serverOrDaemon = serverOrDaemon; - hSession->hWorkThread = uv_thread_self(); - hSession->mapTask = new map(); - hSession->listKey = new list; - hSession->uvRef = 0; - // pullup child - WRITE_LOG(LOG_DEBUG, "HdcSessionBase NewSession, sessionId:%u", hSession->sessionId); - - uv_tcp_init(&loopMain, &hSession->ctrlPipe[STREAM_MAIN]); - ++hSession->uvRef; - Base::CreateSocketPair(hSession->ctrlFd); - uv_tcp_open(&hSession->ctrlPipe[STREAM_MAIN], hSession->ctrlFd[STREAM_MAIN]); - uv_read_start((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], Base::AllocBufferCallback, ReadCtrlFromSession); - hSession->ctrlPipe[STREAM_MAIN].data = hSession; - hSession->ctrlPipe[STREAM_WORK].data = hSession; - // Activate USB DAEMON's data channel, may not for use - uv_tcp_init(&loopMain, &hSession->dataPipe[STREAM_MAIN]); - ++hSession->uvRef; - Base::CreateSocketPair(hSession->dataFd); - uv_tcp_open(&hSession->dataPipe[STREAM_MAIN], hSession->dataFd[STREAM_MAIN]); - hSession->dataPipe[STREAM_MAIN].data = hSession; - hSession->dataPipe[STREAM_WORK].data = hSession; - Base::SetTcpOptions(&hSession->dataPipe[STREAM_MAIN]); - ret = MallocSessionByConnectType(hSession); - if (ret) { - delete hSession; - hSession = nullptr; - } else { - AdminSession(OP_ADD, hSession->sessionId, hSession); - } - return hSession; -} - -void HdcSessionBase::FreeSessionByConnectType(HSession hSession) -{ - if (CONN_USB == hSession->connType) { - // ibusb All context is applied for sub-threaded, so it needs to be destroyed in the subline - if (!hSession->hUSB) { - return; - } - HUSB hUSB = hSession->hUSB; - if (!hUSB) { - return; - } -#ifdef HDC_HOST - if (hUSB->devHandle) { - libusb_release_interface(hUSB->devHandle, hUSB->interfaceNumber); - libusb_close(hUSB->devHandle); - hUSB->devHandle = nullptr; - } - - delete[] hUSB->bufDevice; - delete[] hUSB->bufHost; - libusb_free_transfer(hUSB->transferRecv); - libusb_free_transfer(hUSB->transferSend); -#else - if (hUSB->bulkIn > 0) { - close(hUSB->bulkIn); - hUSB->bulkIn = 0; - } - if (hUSB->bulkOut > 0) { - close(hUSB->bulkOut); - hUSB->bulkOut = 0; - } -#endif - delete hSession->hUSB; - hSession->hUSB = nullptr; - } -} - -// work when libuv-handle at struct of HdcSession has all callback finished -void HdcSessionBase::FreeSessionFinally(uv_idle_t *handle) -{ - HSession hSession = (HSession)handle->data; - HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; - if (hSession->uvRef > 0) { - return; - } - // Notify Server or Daemon, just UI or display commandline - thisClass->NotifyInstanceSessionFree(hSession, true); - // all hsession uv handle has been clear - thisClass->AdminSession(OP_REMOVE, hSession->sessionId, nullptr); - WRITE_LOG(LOG_DEBUG, "!!!FreeSessionFinally sessionId:%u finish", hSession->sessionId); - delete hSession; - hSession = nullptr; // fix CodeMars SetNullAfterFree issue - Base::TryCloseHandle((const uv_handle_t *)handle, Base::CloseIdleCallback); - --thisClass->sessionRef; -} - -// work when child-work thread finish -void HdcSessionBase::FreeSessionContinue(HSession hSession) -{ - auto closeSessionTCPHandle = [](uv_handle_t *handle) -> void { - HSession hSession = (HSession)handle->data; - --hSession->uvRef; - Base::TryCloseHandle((uv_handle_t *)handle); - }; - if (CONN_TCP == hSession->connType) { - // Turn off TCP to prevent continuing writing - Base::TryCloseHandle((uv_handle_t *)&hSession->hWorkTCP, true, closeSessionTCPHandle); - } - hSession->availTailIndex = 0; - if (hSession->ioBuf) { - delete[] hSession->ioBuf; - hSession->ioBuf = nullptr; - } - Base::TryCloseHandle((uv_handle_t *)&hSession->ctrlPipe[STREAM_MAIN], true, closeSessionTCPHandle); - Base::TryCloseHandle((uv_handle_t *)&hSession->dataPipe[STREAM_MAIN], true, closeSessionTCPHandle); - delete hSession->mapTask; - HdcAuth::FreeKey(!hSession->serverOrDaemon, hSession->listKey); - delete hSession->listKey; // to clear - FreeSessionByConnectType(hSession); - // finish - Base::IdleUvTask(&loopMain, hSession, FreeSessionFinally); -} - -void HdcSessionBase::FreeSessionOpeate(uv_timer_t *handle) -{ - HSession hSession = (HSession)handle->data; - HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; - if (hSession->sendRef > 0) { - return; - } -#ifdef HDC_HOST - if (hSession->hUSB != nullptr && (!hSession->hUSB->recvIOComplete || !hSession->hUSB->sendIOComplete)) { - return; - } -#endif - // wait workthread to free - if (hSession->ctrlPipe[STREAM_WORK].loop) { - auto ctrl = BuildCtrlString(SP_STOP_SESSION, 0, nullptr, 0); - Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); - WRITE_LOG(LOG_DEBUG, "FreeSession, send workthread fo free. sessionId:%u", hSession->sessionId); - auto callbackCheckFreeSessionContinue = [](uv_timer_t *handle) -> void { - HSession hSession = (HSession)handle->data; - HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; - if (!hSession->childCleared) { - return; - } - Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseTimerCallback); - thisClass->FreeSessionContinue(hSession); - }; - Base::TimerUvTask(&thisClass->loopMain, hSession, callbackCheckFreeSessionContinue); - } else { - thisClass->FreeSessionContinue(hSession); - } - Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseTimerCallback); -} - -void HdcSessionBase::FreeSession(const uint32_t sessionId) -{ - HSession hSession = AdminSession(OP_QUERY, sessionId, nullptr); - if (!hSession) { - return; - } - if (hSession->hWorkThread != uv_thread_self()) { - PushAsyncMessage(hSession->sessionId, ASYNC_FREE_SESSION, nullptr, 0); - return; - } - if (hSession->isDead) { - return; - } - hSession->isDead = true; - Base::TimerUvTask(&loopMain, hSession, FreeSessionOpeate); - NotifyInstanceSessionFree(hSession, false); - WRITE_LOG(LOG_DEBUG, "FreeSession sessionId:%u sendref:%u", hSession->sessionId, uint16_t(hSession->sendRef)); -} - -HSession HdcSessionBase::AdminSession(const uint8_t op, const uint32_t sessionId, HSession hInput) -{ - HSession hRet = nullptr; - switch (op) { - case OP_ADD: - uv_rwlock_wrlock(&lockMapSession); - mapSession[sessionId] = hInput; - uv_rwlock_wrunlock(&lockMapSession); - break; - case OP_REMOVE: - uv_rwlock_wrlock(&lockMapSession); - mapSession.erase(sessionId); - uv_rwlock_wrunlock(&lockMapSession); - break; - case OP_QUERY: - uv_rwlock_rdlock(&lockMapSession); - if (mapSession.count(sessionId)) { - hRet = mapSession[sessionId]; - } - uv_rwlock_rdunlock(&lockMapSession); - break; - case OP_UPDATE: - uv_rwlock_wrlock(&lockMapSession); - // remove old - mapSession.erase(sessionId); - mapSession[hInput->sessionId] = hInput; - uv_rwlock_wrunlock(&lockMapSession); - break; - default: - break; - } - return hRet; -} - -// All in the corresponding sub-thread, no need locks -HTaskInfo HdcSessionBase::AdminTask(const uint8_t op, HSession hSession, const uint32_t channelId, HTaskInfo hInput) -{ - HTaskInfo hRet = nullptr; - map &mapTask = *hSession->mapTask; - switch (op) { - case OP_ADD: - mapTask[channelId] = hInput; - break; - case OP_REMOVE: - mapTask.erase(channelId); - break; - case OP_QUERY: - if (mapTask.count(channelId)) { - hRet = mapTask[channelId]; - } - break; - default: - break; - } - return hRet; -} - -int HdcSessionBase::SendByProtocol(HSession hSession, uint8_t *bufPtr, const int bufLen) -{ - if (hSession->isDead) { - return ERR_SESSION_NOFOUND; - } - int ret = 0; - ++hSession->sendRef; - switch (hSession->connType) { - case CONN_TCP: { - if (hSession->hWorkThread == uv_thread_self()) { - ret = Base::SendToStreamEx((uv_stream_t *)&hSession->hWorkTCP, bufPtr, bufLen, nullptr, - (void *)FinishWriteSessionTCP, bufPtr); - } else if (hSession->hWorkChildThread == uv_thread_self()) { - ret = Base::SendToStreamEx((uv_stream_t *)&hSession->hChildWorkTCP, bufPtr, bufLen, nullptr, - (void *)FinishWriteSessionTCP, bufPtr); - } else { - WRITE_LOG(LOG_FATAL, "SendByProtocol uncontrol send"); - ret = ERR_API_FAIL; - } - break; - } - case CONN_USB: { - HdcUSBBase *pUSB = ((HdcUSBBase *)hSession->classModule); - ret = pUSB->SendUSBBlock(hSession, bufPtr, bufLen); - delete[] bufPtr; - break; - } - default: - break; - } - return ret; -} - -int HdcSessionBase::Send(const uint32_t sessionId, const uint32_t channelId, const uint16_t commandFlag, - const uint8_t *data, const int dataSize) -{ - HSession hSession = AdminSession(OP_QUERY, sessionId, nullptr); - if (!hSession) { - WRITE_LOG(LOG_DEBUG, "Send to offline device, drop it, sessionId:%u", sessionId); - return ERR_SESSION_NOFOUND; - } - PayloadProtect protectBuf; // noneed convert to big-endian - protectBuf.channelId = channelId; - protectBuf.commandFlag = commandFlag; - protectBuf.checkSum = (ENABLE_IO_CHECKSUM && dataSize > 0) ? Base::CalcCheckSum(data, dataSize) : 0; - protectBuf.vCode = payloadProtectStaticVcode; - string s = SerialStruct::SerializeToString(protectBuf); - // reserve for encrypt here - // xx-encrypt - - PayloadHead payloadHead; // need convert to big-endian - Base::ZeroStruct(payloadHead); - payloadHead.flag[0] = PACKET_FLAG.at(0); - payloadHead.flag[1] = PACKET_FLAG.at(1); - payloadHead.protocolVer = VER_PROTOCOL; - payloadHead.headSize = htons(s.size()); - payloadHead.dataSize = htonl(dataSize); - int finalBufSize = sizeof(PayloadHead) + s.size() + dataSize; - uint8_t *finayBuf = new uint8_t[finalBufSize](); - if (finayBuf == nullptr) { - return ERR_BUF_ALLOC; - } - bool bufRet = false; - do { - if (memcpy_s(finayBuf, sizeof(PayloadHead), reinterpret_cast(&payloadHead), sizeof(PayloadHead))) { - break; - } - if (memcpy_s(finayBuf + sizeof(PayloadHead), s.size(), - reinterpret_cast(const_cast(s.c_str())), s.size())) { - break; - } - if (dataSize > 0 && memcpy_s(finayBuf + sizeof(PayloadHead) + s.size(), dataSize, data, dataSize)) { - break; - } - bufRet = true; - } while (false); - if (!bufRet) { - delete[] finayBuf; - return ERR_BUF_COPY; - } - return SendByProtocol(hSession, finayBuf, finalBufSize); -} - -int HdcSessionBase::DecryptPayload(HSession hSession, PayloadHead *payloadHeadBe, uint8_t *encBuf) -{ - PayloadProtect protectBuf; - Base::ZeroStruct(protectBuf); - uint16_t headSize = ntohs(payloadHeadBe->headSize); - int dataSize = ntohl(payloadHeadBe->dataSize); - string encString(reinterpret_cast(encBuf), headSize); - SerialStruct::ParseFromString(protectBuf, encString); - if (protectBuf.vCode != payloadProtectStaticVcode) { - WRITE_LOG(LOG_FATAL, "Session recv static vcode failed"); - return ERR_BUF_CHECK; - } - uint8_t *data = encBuf + headSize; - if (protectBuf.checkSum != 0 && (protectBuf.checkSum != Base::CalcCheckSum(data, dataSize))) { - WRITE_LOG(LOG_FATAL, "Session recv CalcCheckSum failed"); - return ERR_BUF_CHECK; - } - if (!FetchCommand(hSession, protectBuf.channelId, protectBuf.commandFlag, data, dataSize)) { - WRITE_LOG(LOG_WARN, "FetchCommand failed"); - return ERR_GENERIC; - } - return RET_SUCCESS; -} - -int HdcSessionBase::OnRead(HSession hSession, uint8_t *bufPtr, const int bufLen) -{ - int ret = ERR_GENERIC; - if (memcmp(bufPtr, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { - return ERR_BUF_CHECK; - } - struct PayloadHead *payloadHead = (struct PayloadHead *)bufPtr; - int tobeReadLen = ntohl(payloadHead->dataSize) + ntohs(payloadHead->headSize); - int packetHeadSize = sizeof(struct PayloadHead); - if (tobeReadLen <= 0 || (uint32_t)tobeReadLen > HDC_BUF_MAX_BYTES) { - // max 1G - return ERR_BUF_CHECK; - } - if (bufLen - packetHeadSize < tobeReadLen) { - return 0; - } - if (DecryptPayload(hSession, payloadHead, bufPtr + packetHeadSize)) { - return ERR_BUF_CHECK; - } - ret = packetHeadSize + tobeReadLen; - return ret; -} - -// Returns <0 error;> 0 receives the number of bytes; 0 untreated -int HdcSessionBase::FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read) -{ - HdcSessionBase *ptrConnect = (HdcSessionBase *)hSession->classInstance; - int indexBuf = 0; - int childRet = 0; - if (read < 0) { - return ERR_IO_FAIL; - } - hSession->availTailIndex += read; - while (!hSession->isDead && hSession->availTailIndex > static_cast(sizeof(PayloadHead))) { - childRet = ptrConnect->OnRead(hSession, ioBuf + indexBuf, hSession->availTailIndex); - if (childRet > 0) { - hSession->availTailIndex -= childRet; - indexBuf += childRet; - } else if (childRet == 0) { - // Not enough a IO - break; - } else { - // <0 - hSession->availTailIndex = 0; // Preventing malicious data packages - indexBuf = ERR_BUF_SIZE; - break; - } - // It may be multi-time IO to merge in a BUF, need to loop processing - } - if (indexBuf > 0 && hSession->availTailIndex > 0) { - memmove_s(hSession->ioBuf, hSession->bufSize, hSession->ioBuf + indexBuf, hSession->availTailIndex); - uint8_t *bufToZero = (uint8_t *)(hSession->ioBuf + hSession->availTailIndex); - Base::ZeroBuf(bufToZero, hSession->bufSize - hSession->availTailIndex); - } - return indexBuf; -} - -void HdcSessionBase::AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) -{ - HSession context = (HSession)handle->data; - Base::ReallocBuf(&context->ioBuf, &context->bufSize, context->availTailIndex, sizeWanted); - buf->base = (char *)context->ioBuf + context->availTailIndex; - buf->len = context->bufSize - context->availTailIndex - 1; // 16Bytes are retained to prevent memory sticking - assert(buf->len >= 0); -} - -void HdcSessionBase::FinishWriteSessionTCP(uv_write_t *req, int status) -{ - HSession hSession = (HSession)req->handle->data; - --hSession->sendRef; - HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; - if (status < 0) { - Base::TryCloseHandle((uv_handle_t *)req->handle); - if (!hSession->isDead && !hSession->sendRef) { - WRITE_LOG(LOG_DEBUG, "FinishWriteSessionTCP freesession :%p", hSession); - thisClass->FreeSession(hSession->sessionId); - } - } - delete[]((uint8_t *)req->data); - delete req; -} - -bool HdcSessionBase::DispatchSessionThreadCommand(uv_stream_t *uvpipe, HSession hSession, const uint8_t *baseBuf, - const int bytesIO) -{ - bool ret = true; - uint8_t flag = *(uint8_t *)baseBuf; - - switch (flag) { - case SP_JDWP_NEWFD: { - JdwpNewFileDescriptor(baseBuf, bytesIO); - break; - } - default: - WRITE_LOG(LOG_WARN, "Not support session command"); - break; - } - return ret; -} - -void HdcSessionBase::ReadCtrlFromSession(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf) -{ - HSession hSession = (HSession)uvpipe->data; - HdcSessionBase *hSessionBase = (HdcSessionBase *)hSession->classInstance; - while (true) { - if (nread < 0) { - WRITE_LOG(LOG_DEBUG, "SessionCtrl failed,%s", uv_strerror(nread)); - break; - } - if (nread > 64) { // 64 : max length - WRITE_LOG(LOG_WARN, "HdcSessionBase read overlap data"); - break; - } - // only one command, no need to split command from stream - // if add more commands, consider the format command - hSessionBase->DispatchSessionThreadCommand(uvpipe, hSession, (uint8_t *)buf->base, nread); - break; - } - delete[] buf->base; -} - -bool HdcSessionBase::WorkThreadStartSession(HSession hSession) -{ - bool regOK = false; - int childRet = 0; - if (hSession->connType == CONN_TCP) { - HdcTCPBase *pTCPBase = (HdcTCPBase *)hSession->classModule; - hSession->hChildWorkTCP.data = hSession; - if ((childRet = uv_tcp_init(&hSession->childLoop, &hSession->hChildWorkTCP)) < 0) { - WRITE_LOG(LOG_DEBUG, "HdcSessionBase SessionCtrl failed 1"); - return false; - } - if ((childRet = uv_tcp_open(&hSession->hChildWorkTCP, hSession->fdChildWorkTCP)) < 0) { - WRITE_LOG(LOG_DEBUG, "SessionCtrl failed 2,fd:%d,str:%s", hSession->fdChildWorkTCP, uv_strerror(childRet)); - return false; - } - Base::SetTcpOptions((uv_tcp_t *)&hSession->hChildWorkTCP); - uv_read_start((uv_stream_t *)&hSession->hChildWorkTCP, AllocCallback, pTCPBase->ReadStream); - regOK = true; - } else { // USB - HdcUSBBase *pUSBBase = (HdcUSBBase *)hSession->classModule; - WRITE_LOG(LOG_DEBUG, "USB ReadyForWorkThread"); - regOK = pUSBBase->ReadyForWorkThread(hSession); - } - if (regOK && hSession->serverOrDaemon) { - // session handshake step1 - SessionHandShake handshake; - Base::ZeroStruct(handshake); - handshake.banner = HANDSHAKE_MESSAGE; - handshake.sessionId = hSession->sessionId; - handshake.connectKey = hSession->connectKey; - handshake.authType = AUTH_NONE; - string hs = SerialStruct::SerializeToString(handshake); - Send(hSession->sessionId, 0, CMD_KERNEL_HANDSHAKE, (uint8_t *)hs.c_str(), hs.size()); - } - return regOK; -} - -vector HdcSessionBase::BuildCtrlString(InnerCtrlCommand command, uint32_t channelId, uint8_t *data, - int dataSize) -{ - vector ret; - while (true) { - if (dataSize > BUF_SIZE_MICRO) { - break; - } - CtrlStruct ctrl; - Base::ZeroStruct(ctrl); - ctrl.command = command; - ctrl.channelId = channelId; - ctrl.dataSize = dataSize; - if (dataSize > 0 && data != nullptr && memcpy_s(ctrl.data, sizeof(ctrl.data), data, dataSize) != EOK) { - break; - } - uint8_t *buf = reinterpret_cast(&ctrl); - ret.insert(ret.end(), buf, buf + sizeof(CtrlStruct)); - break; - } - return ret; -} - -bool HdcSessionBase::DispatchMainThreadCommand(HSession hSession, const CtrlStruct *ctrl) -{ - bool ret = true; - uint32_t channelId = ctrl->channelId; // if send not set, it is zero - switch (ctrl->command) { - case SP_START_SESSION: { - WRITE_LOG(LOG_DEBUG, "Dispatch MainThreadCommand START_SESSION sessionId:%u instance:%s", - hSession->sessionId, hSession->serverOrDaemon ? "server" : "daemon"); - ret = WorkThreadStartSession(hSession); - break; - } - case SP_STOP_SESSION: { - WRITE_LOG(LOG_DEBUG, "Dispatch MainThreadCommand STOP_SESSION sessionId:%u", hSession->sessionId); - auto closeSessionChildThreadTCPHandle = [](uv_handle_t *handle) -> void { - HSession hSession = (HSession)handle->data; - Base::TryCloseHandle((uv_handle_t *)handle); - if (--hSession->uvChildRef == 0) { - uv_stop(&hSession->childLoop); - }; - }; - hSession->uvChildRef += 2; - if (hSession->hChildWorkTCP.loop) { // maybe not use it - ++hSession->uvChildRef; - Base::TryCloseHandle((uv_handle_t *)&hSession->hChildWorkTCP, true, closeSessionChildThreadTCPHandle); - } - Base::TryCloseHandle((uv_handle_t *)&hSession->ctrlPipe[STREAM_WORK], true, - closeSessionChildThreadTCPHandle); - Base::TryCloseHandle((uv_handle_t *)&hSession->dataPipe[STREAM_WORK], true, - closeSessionChildThreadTCPHandle); - break; - } - case SP_ATTACH_CHANNEL: { - if (!serverOrDaemon) { - break; // Only Server has this feature - } - AttachChannel(hSession, channelId); - break; - } - case SP_DEATCH_CHANNEL: { - if (!serverOrDaemon) { - break; // Only Server has this feature - } - DeatchChannel(hSession, channelId); - break; - } - default: - WRITE_LOG(LOG_WARN, "Not support main command"); - ret = false; - break; - } - return ret; -} - -// Several bytes of control instructions, generally do not stick -void HdcSessionBase::ReadCtrlFromMain(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf) -{ - HSession hSession = (HSession)uvpipe->data; - HdcSessionBase *hSessionBase = (HdcSessionBase *)hSession->classInstance; - int formatCommandSize = sizeof(CtrlStruct); - int index = 0; - bool ret = true; - while (true) { - if (nread < 0) { - WRITE_LOG(LOG_DEBUG, "SessionCtrl failed,%s", uv_strerror(nread)); - ret = false; - break; - } - if (nread % formatCommandSize != 0) { - WRITE_LOG(LOG_FATAL, "ReadCtrlFromMain size failed, nread == %d", nread); - ret = false; - break; - } - CtrlStruct *ctrl = reinterpret_cast(buf->base + index); - if (!(ret = hSessionBase->DispatchMainThreadCommand(hSession, ctrl))) { - ret = false; - break; - } - index += sizeof(CtrlStruct); - if (index >= nread) { - break; - } - } - delete[] buf->base; -} - -void HdcSessionBase::ReChildLoopForSessionClear(HSession hSession) -{ - // Restart loop close task - ClearOwnTasks(hSession, 0); - auto clearTaskForSessionFinish = [](uv_idle_t *handle) -> void { - HSession hSession = (HSession)handle->data; - for (auto v : *hSession->mapTask) { - HTaskInfo hTask = (HTaskInfo)v.second; - if (!hTask->taskFree) - return; - } - // all task has been free - uv_close((uv_handle_t *)handle, Base::CloseIdleCallback); - uv_stop(&hSession->childLoop); // stop ReChildLoopForSessionClear pendding - }; - Base::IdleUvTask(&hSession->childLoop, hSession, clearTaskForSessionFinish); - uv_run(&hSession->childLoop, UV_RUN_DEFAULT); - // clear - Base::TryCloseLoop(&hSession->childLoop, "Session childUV"); -} - -void HdcSessionBase::SessionWorkThread(uv_work_t *arg) -{ - int childRet = 0; - HSession hSession = (HSession)arg->data; - HdcSessionBase *thisClass = (HdcSessionBase *)hSession->classInstance; - uv_loop_init(&hSession->childLoop); - hSession->hWorkChildThread = uv_thread_self(); - if ((childRet = uv_tcp_init(&hSession->childLoop, &hSession->ctrlPipe[STREAM_WORK])) < 0) { - WRITE_LOG(LOG_DEBUG, "SessionCtrl err1, %s", uv_strerror(childRet)); - } - if ((childRet = uv_tcp_open(&hSession->ctrlPipe[STREAM_WORK], hSession->ctrlFd[STREAM_WORK])) < 0) { - WRITE_LOG(LOG_DEBUG, "SessionCtrl err2, %s fd:%d", uv_strerror(childRet), hSession->ctrlFd[STREAM_WORK]); - } - uv_read_start((uv_stream_t *)&hSession->ctrlPipe[STREAM_WORK], Base::AllocBufferCallback, ReadCtrlFromMain); - WRITE_LOG(LOG_DEBUG, "!!!Workthread run begin, sessionId:%u instance:%s", hSession->sessionId, - thisClass->serverOrDaemon ? "server" : "daemon"); - uv_run(&hSession->childLoop, UV_RUN_DEFAULT); // work pendding - WRITE_LOG(LOG_DEBUG, "!!!Workthread run again, sessionId:%u", hSession->sessionId); - // main loop has exit - thisClass->ReChildLoopForSessionClear(hSession); // work pending again - hSession->childCleared = true; - WRITE_LOG(LOG_DEBUG, "!!!Workthread run finish, sessionId:%u workthread:%p", hSession->sessionId, uv_thread_self()); -} - -// clang-format off -void HdcSessionBase::LogMsg(const uint32_t sessionId, const uint32_t channelId, - MessageLevel level, const char *msg, ...) -// clang-format on -{ - va_list vaArgs; - va_start(vaArgs, msg); - string log = Base::StringFormat(msg, vaArgs); - va_end(vaArgs); - vector buf; - buf.push_back(level); - buf.insert(buf.end(), log.c_str(), log.c_str() + log.size()); - ServerCommand(sessionId, channelId, CMD_KERNEL_ECHO, buf.data(), buf.size()); -} - -// Heavy and time-consuming work was putted in the new thread to do, and does -// not occupy the main thread -bool HdcSessionBase::DispatchTaskData(HSession hSession, const uint32_t channelId, const uint16_t command, - uint8_t *payload, int payloadSize) -{ - bool ret = false; - while (true) { - HTaskInfo hTaskInfo = AdminTask(OP_QUERY, hSession, channelId, nullptr); - if (!hTaskInfo) { - WRITE_LOG(LOG_DEBUG, "New HTaskInfo"); - hTaskInfo = new TaskInformation(); - hTaskInfo->channelId = channelId; - hTaskInfo->sessionId = hSession->sessionId; - hTaskInfo->runLoop = &hSession->childLoop; - hTaskInfo->serverOrDaemon = serverOrDaemon; - } - if (hTaskInfo->taskStop) { - WRITE_LOG(LOG_DEBUG, "RedirectToTask jump stopped task:%d", channelId); - break; - } - if (hTaskInfo->taskFree) { - WRITE_LOG(LOG_DEBUG, "Jump delete HTaskInfo"); - break; - } - bool result = RedirectToTask(hTaskInfo, hSession, channelId, command, payload, payloadSize); - if (!hTaskInfo->hasInitial) { - AdminTask(OP_ADD, hSession, channelId, hTaskInfo); - hTaskInfo->hasInitial = true; - } - if (result) { - ret = true; - } - break; - } - return ret; -} - -void HdcSessionBase::PostStopInstanceMessage(bool restart) -{ - PushAsyncMessage(0, ASYNC_STOP_MAINLOOP, nullptr, 0); - WRITE_LOG(LOG_DEBUG, "StopDaemon has sended"); - wantRestart = restart; -} -} // namespace Hdc diff --git a/services/flashd/common/session.h b/services/flashd/common/session.h deleted file mode 100755 index fe580717..00000000 --- a/services/flashd/common/session.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_SESSION_H -#define HDC_SESSION_H -#include "common.h" - -namespace Hdc { -enum TaskType { TYPE_UNITY, TYPE_SHELL, TASK_FILE, TASK_FORWARD, TASK_APP, TASK_UPDATER }; - -class HdcSessionBase { -public: - enum AuthType { AUTH_NONE, AUTH_TOKEN, AUTH_SIGNATURE, AUTH_PUBLICKEY, AUTH_OK }; - struct SessionHandShake { - string banner; // must first index - // auth none - uint8_t authType; - uint32_t sessionId; - string connectKey; - string buf; - }; - struct CtrlStruct { - InnerCtrlCommand command; - uint32_t channelId; - uint8_t dataSize; - uint8_t data[BUF_SIZE_MICRO]; - }; - struct PayloadProtect { // reserve for encrypt and decrypt - uint32_t channelId; - uint32_t commandFlag; - uint8_t checkSum; // enable it will be lose about 20% speed - uint8_t vCode; - }; - - HdcSessionBase(bool serverOrDaemonIn); - virtual ~HdcSessionBase(); - virtual void AttachChannel(HSession hSession, const uint32_t channelId) {}; - virtual void DeatchChannel(HSession hSession, const uint32_t channelId) {}; - virtual bool RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, - const uint16_t command, uint8_t *payload, const int payloadSize) - { - return true; - } - virtual void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear) - { - } - // Thread security interface for global stop programs - void PostStopInstanceMessage(bool restart = false); - void ReMainLoopForInstanceClear(); - // server, Two parameters in front of call can be empty - void LogMsg(const uint32_t sessionId, const uint32_t channelId, MessageLevel level, const char *msg, ...); - static void AllocCallback(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf); - static void MainAsyncCallback(uv_async_t *handle); - static void FinishWriteSessionTCP(uv_write_t *req, int status); - static void SessionWorkThread(uv_work_t *arg); - static void ReadCtrlFromMain(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf); - static void ReadCtrlFromSession(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf); - HSession QueryUSBDeviceRegister(void *pDev, int busIDIn, int devIDIn); - HSession MallocSession(bool serverOrDaemon, const ConnType connType, void *classModule, uint32_t sessionId = 0); - void FreeSession(const uint32_t sessionId); - void WorkerPendding(); - int OnRead(HSession hSession, uint8_t *bufPtr, const int bufLen); - int Send(const uint32_t sessionId, const uint32_t channelId, const uint16_t commandFlag, const uint8_t *data, - const int dataSize); - int SendByProtocol(HSession hSession, uint8_t *bufPtr, const int bufLen); - HSession AdminSession(const uint8_t op, const uint32_t sessionId, HSession hInput); - int FetchIOBuf(HSession hSession, uint8_t *ioBuf, int read); - void PushAsyncMessage(const uint32_t sessionId, const uint8_t method, const void *data, const int dataSize); - HTaskInfo AdminTask(const uint8_t op, HSession hSession, const uint32_t channelId, HTaskInfo hInput); - bool DispatchTaskData(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, - int payloadSize); - void EnumUSBDeviceRegister(void (*pCallBack)(HSession hSession)); - void ClearOwnTasks(HSession hSession, const uint32_t channelIDInput); - virtual bool FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, - int payloadSize) - { - return true; - } - virtual bool ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command, - uint8_t *bufPtr, const int size) - { - return true; - } - virtual bool RemoveInstanceTask(const uint8_t op, HTaskInfo hTask) - { - return true; - } - bool WantRestart() - { - return wantRestart; - } - static vector BuildCtrlString(InnerCtrlCommand command, uint32_t channelId, uint8_t *data, int dataSize); - uv_loop_t loopMain; - bool serverOrDaemon; - uv_async_t asyncMainLoop; - uv_rwlock_t mainAsync; - list lstMainThreadOP; - void *ctxUSB; - -protected: - struct PayloadHead { - uint8_t flag[2]; - uint8_t reserve[2]; // encrypt'flag or others options - uint8_t protocolVer; - uint16_t headSize; - uint32_t dataSize; - } __attribute__((packed)); - void ClearSessions(); - virtual void JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO) - { - } - // must be define in haderfile, cannot in cpp file - template - bool TaskCommandDispatch(HTaskInfo hTaskInfo, uint8_t taskType, const uint16_t command, uint8_t *payload, - const int payloadSize) - { - bool ret = true; - T *ptrTask = nullptr; - if (!hTaskInfo->hasInitial) { - ptrTask = new T(hTaskInfo); - hTaskInfo->taskClass = ptrTask; - hTaskInfo->taskType = taskType; - } else { - ptrTask = (T *)hTaskInfo->taskClass; - } - if (!ptrTask->CommandDispatch(command, payload, payloadSize)) { - ptrTask->TaskFinish(); - } - return ret; - } - template bool DoTaskRemove(HTaskInfo hTaskInfo, const uint8_t op) - { - T *ptrTask = (T *)hTaskInfo->taskClass; - if (OP_CLEAR == op) { - ptrTask->StopTask(); - } else if (OP_REMOVE == op) { - if (!ptrTask->ReadyForRelease()) { - return false; - } - delete ptrTask; - } - return true; - } - bool wantRestart; - -private: - virtual void ClearInstanceResource() - { - } - int DecryptPayload(HSession hSession, PayloadHead *payloadHeadBe, uint8_t *encBuf); - bool DispatchMainThreadCommand(HSession hSession, const CtrlStruct *ctrl); - bool DispatchSessionThreadCommand(uv_stream_t *uvpipe, HSession hSession, const uint8_t *baseBuf, - const int bytesIO); - bool BeginRemoveTask(HTaskInfo hTask); - bool TryRemoveTask(HTaskInfo hTask); - void ReChildLoopForSessionClear(HSession hSession); - void FreeSessionContinue(HSession hSession); - static void FreeSessionFinally(uv_idle_t *handle); - static void AsyncMainLoopTask(uv_idle_t *handle); - static void FreeSessionOpeate(uv_timer_t *handle); - int MallocSessionByConnectType(HSession hSession); - void FreeSessionByConnectType(HSession hSession); - bool WorkThreadStartSession(HSession hSession); - uint32_t GetSessionPseudoUid(); - - map mapSession; - uv_rwlock_t lockMapSession; - std::atomic sessionRef = 0; - const uint8_t payloadProtectStaticVcode = 0x09; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/common/task.cpp b/services/flashd/common/task.cpp deleted file mode 100755 index 11461858..00000000 --- a/services/flashd/common/task.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "task.h" - -namespace Hdc { -// ----------------------------------------------------------- -// notice!!! The constructor is called at the Child thread, so in addition to initialization, do not excess actions, if -// destructor is required, please clean up in the subclasses. -HdcTaskBase::HdcTaskBase(HTaskInfo hTaskInfo) -{ - taskInfo = hTaskInfo; - loopTask = hTaskInfo->runLoop; - clsSession = hTaskInfo->ownerSessionClass; - childReady = false; - singalStop = false; - refCount = 0; -} - -HdcTaskBase::~HdcTaskBase() -{ - WRITE_LOG(LOG_DEBUG, "~HdcTaskBase"); -} - -bool HdcTaskBase::ReadyForRelease() -{ - return refCount == 0; -} - -// Only the Task work thread call is allowed to use only when Workfortask returns FALSE. -void HdcTaskBase::TaskFinish() -{ - uint8_t count = 1; - SendToAnother(CMD_KERNEL_CHANNEL_CLOSE, &count, 1); - WRITE_LOG(LOG_DEBUG, "HdcTaskBase::TaskFinish notify"); -} - -bool HdcTaskBase::SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size) -{ - if (singalStop) { - return false; - } - HdcSessionBase *sessionBase = reinterpret_cast(taskInfo->ownerSessionClass); - return sessionBase->Send(taskInfo->sessionId, taskInfo->channelId, command, bufPtr, size) > 0; -} - -void HdcTaskBase::LogMsg(MessageLevel level, const char *msg, ...) -{ - va_list vaArgs; - va_start(vaArgs, msg); - string log = Base::StringFormat(msg, vaArgs); - va_end(vaArgs); - HdcSessionBase *sessionBase = reinterpret_cast(clsSession); - sessionBase->LogMsg(taskInfo->sessionId, taskInfo->channelId, level, log.c_str()); -} - -void HdcTaskBase::SendRawData(uint8_t *bufPtr, const int size) -{ - HdcSessionBase *sessionBase = (HdcSessionBase *)clsSession; - sessionBase->ServerCommand(taskInfo->sessionId, - taskInfo->channelId, CMD_KERNEL_ECHO_RAW, bufPtr, size); -} - -bool HdcTaskBase::ServerCommand(const uint16_t command, uint8_t *bufPtr, const int size) -{ - HdcSessionBase *hSession = (HdcSessionBase *)taskInfo->ownerSessionClass; - return hSession->ServerCommand(taskInfo->sessionId, taskInfo->channelId, command, bufPtr, size); -} - -// cross thread -int HdcTaskBase::ThreadCtrlCommunicate(const uint8_t *bufPtr, const int size) -{ - HdcSessionBase *sessionBase = (HdcSessionBase *)taskInfo->ownerSessionClass; - HSession hSession = sessionBase->AdminSession(OP_QUERY, taskInfo->sessionId, nullptr); - if (!hSession) { - return -1; - } - uv_stream_t *handleStream = nullptr; - if (uv_thread_self() == hSession->hWorkThread) { - handleStream = (uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN]; - } else if (uv_thread_self() == hSession->hWorkChildThread) { - handleStream = (uv_stream_t *)&hSession->ctrlPipe[STREAM_WORK]; - } else { - return ERR_GENERIC; - } - return Base::SendToStream(handleStream, bufPtr, size); -} -} \ No newline at end of file diff --git a/services/flashd/common/task.h b/services/flashd/common/task.h deleted file mode 100755 index 0d0d5a67..00000000 --- a/services/flashd/common/task.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_TASK_H -#define HDC_TASK_H -#include "common.h" - -namespace Hdc { -// Only allow inheritance -class HdcTaskBase { -public: - HdcTaskBase(HTaskInfo hTaskInfo); - virtual ~HdcTaskBase(); - virtual bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) - { - return true; - } - // The following two functions are used to clean up. To ensure that subclasses are safely cleaned, each subclass is - // directly instantified of these two virtual functions. - virtual void StopTask() - { - singalStop = true; // default opeartion - } - bool ReadyForRelease(); - void TaskFinish(); - void SendRawData(uint8_t *bufPtr, const int size); -protected: // D/S==daemon/server - bool SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size); // D / S corresponds to the Task class - void LogMsg(MessageLevel level, const char *msg, ...); // D / S log Send to Client - bool ServerCommand(const uint16_t command, uint8_t *bufPtr, const int size); // D / s command is sent to Server - int ThreadCtrlCommunicate(const uint8_t *bufPtr, const int size); // main thread and session thread - - uv_loop_t *loopTask; // childuv pointer - void *clsSession; - // Task has stopped running. When Task is officially running, set True as soon as possible, set FALSE after the last - // step, when the value is false, the Task class will be destructured as soon as possible - bool childReady; // Subcompulents have been prepared - bool singalStop; // Request stop signal - HTaskInfo taskInfo; - uint32_t refCount; - -private: -}; -} // namespace Hdc - -#endif \ No newline at end of file diff --git a/services/flashd/common/tcp.cpp b/services/flashd/common/tcp.cpp deleted file mode 100755 index 18f267c7..00000000 --- a/services/flashd/common/tcp.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "tcp.h" - -namespace Hdc { -HdcTCPBase::HdcTCPBase(const bool serverOrDaemonIn, void *ptrMainBase) -{ - // Calling the initialization - InitialChildClass(serverOrDaemonIn, ptrMainBase); -} - -HdcTCPBase::~HdcTCPBase() -{ -} - -// Subclasses must be explicitly called -void HdcTCPBase::InitialChildClass(const bool serverOrDaemonIn, void *ptrMainBase) -{ - serverOrDaemon = serverOrDaemonIn; - clsMainBase = ptrMainBase; -} - -void HdcTCPBase::RecvUDP(uv_udp_t *handle, ssize_t nread, const uv_buf_t *rcvbuf, const struct sockaddr *addr, - unsigned flags) -{ - while (true) { - HdcTCPBase *thisClass = (HdcTCPBase *)handle->data; - if (nread <= 0) { - // ==0 finish;<0 error - break; - } - WRITE_LOG(LOG_DEBUG, "RecvUDP %s", rcvbuf->base); - if (strncmp(rcvbuf->base, HANDSHAKE_MESSAGE.c_str(), HANDSHAKE_MESSAGE.size())) { - break; - } - thisClass->RecvUDPEntry(addr, handle, rcvbuf); - break; - } - delete[] rcvbuf->base; -} - -void HdcTCPBase::AllocStreamUDP(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf) -{ - int bufLen = BUF_SIZE_DEFAULT; - char *pRecvBuf = (char *)new uint8_t[bufLen](); - if (!pRecvBuf) { - return; - } - buf->base = pRecvBuf; - buf->len = bufLen; -} - -void HdcTCPBase::SendUDPFinish(uv_udp_send_t *req, int status) -{ - delete req; -} - -void HdcTCPBase::ReadStream(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf) -{ - HSession hSession = (HSession)tcp->data; - HdcTCPBase *thisClass = (HdcTCPBase *)hSession->classModule; - HdcSessionBase *hSessionBase = (HdcSessionBase *)thisClass->clsMainBase; - bool ret = false; - while (true) { - if (nread == UV_ENOBUFS) { - WRITE_LOG(LOG_DEBUG, "Session IOBuf max"); - break; - } else if (nread < 0) { - // I originally in the IO main thread, no need to send asynchronous messages, close the socket as soon as - // possible - WRITE_LOG(LOG_DEBUG, "HdcTCPBase::ReadStream < 0 %s", uv_strerror(nread)); - break; - } - if (hSessionBase->FetchIOBuf(hSession, hSession->ioBuf, nread) < 0) { - break; - } - ret = true; - break; - } - if (!ret) { - // The first time is closed first, prevent the write function from continuing to write - Base::TryCloseHandle(reinterpret_cast(tcp)); - hSessionBase->FreeSession(hSession->sessionId); - } -} -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/common/tcp.h b/services/flashd/common/tcp.h deleted file mode 100755 index e7f32a27..00000000 --- a/services/flashd/common/tcp.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_TCP_H -#define HDC_TCP_H -#include "common.h" - -namespace Hdc { -class HdcTCPBase { -public: - HdcTCPBase(const bool serverOrDaemonIn, void *ptrMainBase); - virtual ~HdcTCPBase(); - static void ReadStream(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf); - -protected: - virtual void RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf) - { - } - static void RecvUDP( - uv_udp_t *handle, ssize_t nread, const uv_buf_t *rcvbuf, const struct sockaddr *addr, unsigned flags); - static void SendUDPFinish(uv_udp_send_t *req, int status); - static void AllocStreamUDP(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf); - - void *clsMainBase; - bool serverOrDaemon; - -private: - void InitialChildClass(const bool serverOrDaemonIn, void *ptrMainBase); -}; -} // namespace Hdc - -#endif \ No newline at end of file diff --git a/services/flashd/common/transfer.cpp b/services/flashd/common/transfer.cpp deleted file mode 100755 index fc983cfd..00000000 --- a/services/flashd/common/transfer.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "transfer.h" -#include "serial_struct.h" -#include -#ifdef HARMONY_PROJECT -#include -#endif - -namespace Hdc { -constexpr uint64_t HDC_TIME_CONVERT_BASE = 1000000000; - -HdcTransferBase::HdcTransferBase(HTaskInfo hTaskInfo) - : HdcTaskBase(hTaskInfo) -{ - ResetCtx(&ctxNow, true); - commandBegin = 0; - commandData = 0; -} - -HdcTransferBase::~HdcTransferBase() -{ - WRITE_LOG(LOG_DEBUG, "~HdcTransferBase"); -}; - -bool HdcTransferBase::ResetCtx(CtxFile *context, bool full) -{ - context->fsOpenReq.data = context; - context->fsCloseReq.data = context; - context->thisClass = this; - context->closeNotify = false; - context->indexIO = 0; - context->loop = loopTask; - context->cb = OnFileIO; - if (full) { - context->localPath = ""; - context->remotePath = ""; - context->transferBegin = 0; - context->taskQueue.clear(); - Base::ZeroStruct(ctxNow.transferConfig); - } - return true; -} - -int HdcTransferBase::SimpleFileIO(CtxFile *context, uint64_t index, uint8_t *sendBuf, int bytes) -{ - // The first 8 bytes file offset - uint8_t *buf = new uint8_t[bytes](); - CtxFileIO *ioContext = new CtxFileIO(); - bool ret = false; - while (true) { - if (!buf || !ioContext || bytes < 0) { - break; - } - uv_fs_t *req = &ioContext->fs; - ioContext->bufIO = buf; - ioContext->context = context; - req->data = ioContext; - ++refCount; - if (context->master) { // master just read, and slave just write.when master/read, sendBuf can be nullptr - uv_buf_t iov = uv_buf_init(reinterpret_cast(buf), bytes); - uv_fs_read(context->loop, req, context->fsOpenReq.result, &iov, 1, index, context->cb); - } else { - // The US_FS_WRITE here must be brought into the actual file offset, which cannot be incorporated with local - // accumulated index because UV_FS_WRITE will be executed multiple times and then trigger a callback. - if (bytes > 0 && memcpy_s(ioContext->bufIO, bytes, sendBuf, bytes) != EOK) { - break; - } - uv_buf_t iov = uv_buf_init(reinterpret_cast(ioContext->bufIO), bytes); - uv_fs_write(context->loop, req, context->fsOpenReq.result, &iov, 1, index, context->cb); - } - ret = true; - break; - } - if (!ret) { - WRITE_LOG(LOG_WARN, "SimpleFileIO error"); - if (buf != nullptr) { - delete[] buf; - buf = nullptr; - } - if (ioContext != nullptr) { - delete ioContext; - ioContext = nullptr; - } - return -1; - } - return bytes; -} - -void HdcTransferBase::OnFileClose(uv_fs_t *req) -{ - uv_fs_req_cleanup(req); - CtxFile *context = (CtxFile *)req->data; - HdcTransferBase *thisClass = (HdcTransferBase *)context->thisClass; - if (context->closeNotify) { - // close-step2 - thisClass->WhenTransferFinish(context); - } - --thisClass->refCount; - return; -} - -void HdcTransferBase::SetFileTime(CtxFile *context) -{ - if (!context->transferConfig.holdTimestamp) { - return; - } - if (!context->transferConfig.mtime) { - return; - } - uv_fs_t fs; - double aTimeSec = static_cast(context->transferConfig.atime) / HDC_TIME_CONVERT_BASE; - double mTimeSec = static_cast(context->transferConfig.mtime) / HDC_TIME_CONVERT_BASE; - uv_fs_futime(nullptr, &fs, context->fsOpenReq.result, aTimeSec, mTimeSec, nullptr); - uv_fs_req_cleanup(&fs); -} - -bool HdcTransferBase::SendIOPayload(CtxFile *context, int index, uint8_t *data, int dataSize) -{ - TransferPayload payloadHead; - string head; - int compressSize = 0; - int sendBufSize = payloadPrefixReserve + dataSize; - uint8_t *sendBuf = new uint8_t[sendBufSize](); - if (!sendBuf) { - return false; - } - payloadHead.compressType = context->transferConfig.compressType; - payloadHead.uncompressSize = dataSize; - payloadHead.index = index; - if (dataSize > 0) { - switch (payloadHead.compressType) { -#ifdef HARMONY_PROJECT - case COMPRESS_LZ4: { - compressSize = LZ4_compress_default((const char *)data, (char *)sendBuf + payloadPrefixReserve, - dataSize, dataSize); - break; - } -#endif - default: { // COMPRESS_NONE - if (memcpy_s(sendBuf + payloadPrefixReserve, sendBufSize - payloadPrefixReserve, data, dataSize) - != EOK) { - delete[] sendBuf; - return false; - } - compressSize = dataSize; - break; - } - } - } - payloadHead.compressSize = compressSize; - head = SerialStruct::SerializeToString(payloadHead); - if (head.size() + 1 > payloadPrefixReserve) { - delete[] sendBuf; - return false; - } - int errCode = memcpy_s(sendBuf, sendBufSize, head.c_str(), head.size() + 1); - if (errCode != EOK) { - delete[] sendBuf; - return false; - } - bool ret = SendToAnother(commandData, sendBuf, payloadPrefixReserve + compressSize) > 0; - delete[] sendBuf; - return ret; -} - -void HdcTransferBase::OnFileIO(uv_fs_t *req) -{ - bool tryFinishIO = false; - CtxFileIO *contextIO = (CtxFileIO *)req->data; - CtxFile *context = (CtxFile *)contextIO->context; - HdcTransferBase *thisClass = (HdcTransferBase *)context->thisClass; - uint8_t *bufIO = contextIO->bufIO; - uv_fs_req_cleanup(req); - --thisClass->refCount; - while (true) { - if (req->result < 0) { - WRITE_LOG(LOG_DEBUG, "OnFileIO error: %s", uv_strerror((int)req->result)); - context->closeNotify = true; - tryFinishIO = true; - break; - } - context->indexIO += req->result; - if (req->fs_type == UV_FS_READ) { - if (!thisClass->SendIOPayload(context, context->indexIO - req->result, bufIO, req->result)) { - tryFinishIO = true; - break; - } - if (context->indexIO < context->fileSize) { - // read continue until result >0, let single file packet +packet header less than GetMaxBufSize() - constexpr auto maxBufFactor = 0.8; - thisClass->SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize() * maxBufFactor); - } - } else if (req->fs_type == UV_FS_WRITE) { // write - if (context->indexIO >= context->fileSize) { - // The active end must first read it first, but you can't make Finish first, because Slave may not - // end.Only slave receives complete talents Finish - context->closeNotify = true; - tryFinishIO = true; - thisClass->SetFileTime(context); - } - } else { - tryFinishIO = true; - } - break; - } - delete[] bufIO; - delete contextIO; // Req is part of the Contextio structure, no free release - if (tryFinishIO) { - // close-step1 - ++thisClass->refCount; - uv_fs_close(thisClass->loopTask, &context->fsCloseReq, context->fsOpenReq.result, OnFileClose); - } -} - -void HdcTransferBase::OnFileOpen(uv_fs_t *req) -{ - CtxFile *context = (CtxFile *)req->data; - HdcTransferBase *thisClass = (HdcTransferBase *)context->thisClass; - uv_fs_req_cleanup(req); - WRITE_LOG(LOG_DEBUG, "Filemod openfile:%s", context->localPath.c_str()); - --thisClass->refCount; - if (req->result < 0) { - thisClass->LogMsg(MSG_FAIL, "Error opening file: %s, path:%s", uv_strerror((int)req->result), - context->localPath.c_str()); - thisClass->TaskFinish(); - return; - } - thisClass->ResetCtx(context); - if (context->master) { - // init master - uv_fs_t fs; - Base::ZeroStruct(fs.statbuf); - uv_fs_fstat(nullptr, &fs, context->fsOpenReq.result, nullptr); - TransferConfig &st = context->transferConfig; - st.fileSize = fs.statbuf.st_size; - st.optionalName = context->localName; - if (st.holdTimestamp) { - st.atime = fs.statbuf.st_atim.tv_sec * HDC_TIME_CONVERT_BASE + fs.statbuf.st_atim.tv_nsec; - st.mtime = fs.statbuf.st_mtim.tv_sec * HDC_TIME_CONVERT_BASE + fs.statbuf.st_mtim.tv_nsec; - } - st.path = context->remotePath; - // update ctxNow=context child value - context->fileSize = st.fileSize; - - uv_fs_req_cleanup(&fs); - thisClass->CheckMaster(context); - } else { // write - thisClass->SendToAnother(thisClass->commandBegin, nullptr, 0); - } -} - -bool HdcTransferBase::MatchPackageExtendName(string fileName, string extName) -{ - bool match = false; - int subfixIndex = fileName.rfind(extName); - if ((fileName.size() - subfixIndex) != extName.size()) { - return false; - } - match = true; - return match; -} - -// filter can be empty -int HdcTransferBase::GetSubFiles(const char *path, string filter, vector *out) -{ - int retNum = 0; - uv_fs_t req; - Base::ZeroStruct(req); - uv_dirent_t dent; - vector filterStrings; - if (!strlen(path)) { - return retNum; - } - if (filter.size()) { - Base::SplitString(filter, ";", filterStrings); - } - - if (uv_fs_scandir(nullptr, &req, path, 0, nullptr) < 0) { - uv_fs_req_cleanup(&req); - return retNum; - } - while (uv_fs_scandir_next(&req, &dent) != UV_EOF) { - // Skip. File - if (strcmp(dent.name, ".") == 0 || strcmp(dent.name, "..") == 0) - continue; - if (!(static_cast(dent.type) & UV_DIRENT_FILE)) - continue; - string fileName = dent.name; - for (auto &&s : filterStrings) { - int subfixIndex = fileName.rfind(s); - if ((fileName.size() - subfixIndex) != s.size()) - continue; - string fullPath = string(path) + "/"; - fullPath += fileName; - out->push_back(fullPath); - ++retNum; - } - } - uv_fs_req_cleanup(&req); - return retNum; -} - -// https://en.cppreference.com/w/cpp/filesystem/is_directory -// return true if file exist, false if file not exist -bool HdcTransferBase::SmartSlavePath(string &cwd, string &localPath, const char *optName) -{ - if (taskInfo->serverOrDaemon) { - // slave and server - ExtractRelativePath(cwd, localPath); - } - if (Base::CheckDirectoryOrPath(localPath.c_str(), true, false)) { - return true; - } - uv_fs_t req; - int r = uv_fs_lstat(nullptr, &req, localPath.c_str(), nullptr); - uv_fs_req_cleanup(&req); - if (r == 0 && req.statbuf.st_mode & S_IFDIR) { // is dir - localPath = Base::StringFormat("%s%c%s", localPath.c_str(), Base::GetPathSep(), optName); - } - return false; -} - -bool HdcTransferBase::RecvIOPayload(CtxFile *context, uint8_t *data, int dataSize) -{ - uint8_t *clearBuf = nullptr; - string serialStrring((char *)data, payloadPrefixReserve); - TransferPayload pld; - bool ret = false; - SerialStruct::ParseFromString(pld, serialStrring); - clearBuf = new uint8_t[pld.uncompressSize](); - if (!clearBuf) { - return false; - } - int clearSize = 0; - if (pld.compressSize > 0) { - switch (pld.compressType) { -#ifdef HARMONY_PROJECT - case COMPRESS_LZ4: { - clearSize = LZ4_decompress_safe((const char *)data + payloadPrefixReserve, (char *)clearBuf, - pld.compressSize, pld.uncompressSize); - break; - } -#endif - default: { // COMPRESS_NONE - if (memcpy_s(clearBuf, pld.uncompressSize, data + payloadPrefixReserve, pld.compressSize) != EOK) { - delete[] clearBuf; - return false; - } - clearSize = pld.compressSize; - break; - } - } - } - while (true) { - if ((uint32_t)clearSize != pld.uncompressSize) { - break; - } - if (SimpleFileIO(context, pld.index, clearBuf, clearSize) < 0) { - break; - } - ret = true; - break; - } - delete[] clearBuf; - return ret; -} - -bool HdcTransferBase::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) -{ - bool ret = true; - while (true) { - if (command == commandBegin) { - CtxFile *context = &ctxNow; - SimpleFileIO(context, context->indexIO, nullptr, Base::GetMaxBufSize()); - context->transferBegin = Base::GetRuntimeMSec(); - } else if (command == commandData) { - // The size of the actual HOST end may be larger than maxbuf - constexpr auto doubleSize = 2; - if (payloadSize > MAX_SIZE_IOBUF * doubleSize || payloadSize < 0) { - ret = false; - break; - } - // Note, I will trigger FileIO after multiple times. - CtxFile *context = &ctxNow; - if (!RecvIOPayload(context, payload, payloadSize)) { - ret = false; - break; - } - } else { - // Other subclass commands - } - break; - } - return ret; -} - -void HdcTransferBase::ExtractRelativePath(string &cwd, string &path) -{ - bool absPath = Base::IsAbsolutePath(path); - if (!absPath) { - path = cwd + path; - } -} -} // namespace Hdc diff --git a/services/flashd/common/transfer.h b/services/flashd/common/transfer.h deleted file mode 100755 index c03b3dea..00000000 --- a/services/flashd/common/transfer.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_TRANSFER_H -#define HDC_TRANSFER_H -#include "common.h" - -namespace Hdc { -class HdcTransferBase : public HdcTaskBase { -public: - enum CompressType { COMPRESS_NONE, COMPRESS_LZ4, COMPRESS_LZ77, COMPRESS_LZMA, COMPRESS_BROTLI }; - // used for child class - struct TransferConfig { - uint64_t fileSize; - uint64_t atime; // ns - uint64_t mtime; // ns - string options; - string path; - string optionalName; - bool updateIfNew; - uint8_t compressType; - bool holdTimestamp; - string functionName; - string clientCwd; - string reserve1; - string reserve2; - }; - // used for HdcTransferBase. just base class use, not public - struct TransferPayload { - uint64_t index; - uint8_t compressType; - uint32_t compressSize; - uint32_t uncompressSize; - }; - HdcTransferBase(HTaskInfo hTaskInfo); - virtual ~HdcTransferBase(); - virtual void StopTask() - { - } - bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); - -protected: - // Static file context - struct CtxFile { // The structure cannot be initialized by MEMSET - bool master; // Document transmission initiative - bool closeNotify; - void *thisClass; - uint64_t fileSize; - uint64_t indexIO; // Id or written IO bytes - uv_loop_t *loop; - uv_fs_cb cb; - string localName; - string localPath; - string remotePath; - uv_fs_t fsOpenReq; - uv_fs_t fsCloseReq; - uint64_t transferBegin; - vector taskQueue; - TransferConfig transferConfig; // Used for network IO configuration initialization - }; - // Just app-mode use - enum AppModType { - APPMOD_NONE, - APPMOD_INSTALL, - APPMOD_UNINSTALL, - APPMOD_SIDELOAD, - }; - - static void OnFileOpen(uv_fs_t *req); - static void OnFileClose(uv_fs_t *req); - int GetSubFiles(const char *path, string filter, vector *out); - virtual void CheckMaster(CtxFile *context) - { - } - virtual void WhenTransferFinish(CtxFile *context) - { - } - bool MatchPackageExtendName(string fileName, string extName); - bool ResetCtx(CtxFile *context, bool full = false); - bool SmartSlavePath(string &cwd, string &localPath, const char *optName); - void SetFileTime(CtxFile *context); - void ExtractRelativePath(string &cwd, string &path); - - CtxFile ctxNow; - uint16_t commandBegin; - uint16_t commandData; - const string CMD_OPTION_CLIENTCWD = "-cwd"; - const uint8_t payloadPrefixReserve = 64; -private: - // dynamic IO context - struct CtxFileIO { - uv_fs_t fs; - uint8_t *bufIO; - CtxFile *context; - }; - static void OnFileIO(uv_fs_t *req); - int SimpleFileIO(CtxFile *context, uint64_t index, uint8_t *sendBuf, int bytesIO); - bool SendIOPayload(CtxFile *context, int index, uint8_t *data, int dataSize); - bool RecvIOPayload(CtxFile *context, uint8_t *data, int dataSize); -}; -} // namespace Hdc - -#endif \ No newline at end of file diff --git a/services/flashd/common/usb.cpp b/services/flashd/common/usb.cpp deleted file mode 100755 index db39a445..00000000 --- a/services/flashd/common/usb.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "usb.h" - -namespace Hdc { -HdcUSBBase::HdcUSBBase(const bool serverOrDaemonIn, void *ptrMainBase) -{ - serverOrDaemon = serverOrDaemonIn; - clsMainBase = ptrMainBase; - modRunning = true; -} - -HdcUSBBase::~HdcUSBBase() -{ -} - -void HdcUSBBase::ReadUSB(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) -{ - HSession hSession = (HSession)stream->data; - HdcSessionBase *hSessionBase = (HdcSessionBase *)hSession->classInstance; - if (hSessionBase->FetchIOBuf(hSession, hSession->ioBuf, nread) < 0) { - hSessionBase->FreeSession(hSession->sessionId); - } -} - -bool HdcUSBBase::ReadyForWorkThread(HSession hSession) -{ - // Server-end USB IO is handed over to each sub-thread, only the daemon is still read by the main IO to distribute - // to each sub-thread by DataPipe. - if (uv_tcp_init(&hSession->childLoop, &hSession->dataPipe[STREAM_WORK]) - || uv_tcp_open(&hSession->dataPipe[STREAM_WORK], hSession->dataFd[STREAM_WORK])) { - WRITE_LOG(LOG_FATAL, "USBBase ReadyForWorkThread init child TCP failed"); - return false; - } - hSession->dataPipe[STREAM_WORK].data = hSession; - HdcSessionBase *pSession = (HdcSessionBase *)hSession->classInstance; - Base::SetTcpOptions(&hSession->dataPipe[STREAM_WORK]); - if (uv_read_start((uv_stream_t *)&hSession->dataPipe[STREAM_WORK], pSession->AllocCallback, ReadUSB)) { - WRITE_LOG(LOG_FATAL, "USBBase ReadyForWorkThread child TCP read failed"); - return false; - } - WRITE_LOG(LOG_DEBUG, "USBBase ReadyForWorkThread finish"); - return true; -}; - -// USB big data stream, block transmission, mainly to prevent accidental data packets from writing through EP port, -// inserting the send queue causes the program to crash -int HdcUSBBase::SendUSBBlock(HSession hSession, uint8_t *data, const int length) -{ - // Format:USBPacket1 payload1...USBPacketn payloadn; - // [USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] - int maxIOSize = Base::GetMaxBufSize(); - int sizeUSBPacketHead = sizeof(USBHead); - int singleSize = maxIOSize - sizeUSBPacketHead; - int iMod = length % singleSize; - int iCount = (length - iMod) / singleSize + 1; - int offset = 0; - int i = 0; // It doesn't matter of 0 or 1, start from 1 to send it according to the serial number. - uint8_t *ioBuf = new uint8_t[maxIOSize](); - if (!ioBuf) { - return ERR_BUF_ALLOC; - } - for (i = 0; i < iCount; ++i) { - USBHead *pUSBHead = (USBHead *)ioBuf; - int errCode = memcpy_s(pUSBHead->flag, sizeof(pUSBHead->flag), PACKET_FLAG.c_str(), PACKET_FLAG.size()); - if (errCode != EOK) { - offset = ERR_BUF_COPY; - break; - } - pUSBHead->sessionId = hSession->sessionId; - if (i != iCount - 1) { - pUSBHead->dataSize = static_cast(singleSize); - } else { - pUSBHead->dataSize = static_cast(iMod); - pUSBHead->option = pUSBHead->option | USB_OPTION_TAIL; - } - uint8_t *payload = ioBuf + sizeUSBPacketHead; - if (EOK != memcpy_s(payload, maxIOSize - sizeUSBPacketHead, (uint8_t *)data + offset, pUSBHead->dataSize)) { - offset = ERR_BUF_COPY; - break; - } - offset += pUSBHead->dataSize; - if (SendUSBRaw(hSession, ioBuf, sizeUSBPacketHead + pUSBHead->dataSize) <= 0) { - offset = ERR_IO_FAIL; - break; - } - } - delete[] ioBuf; - return offset; -} - -int HdcUSBBase::SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize) -{ - HUSB hUSB = hSession->hUSB; - vector &bufRecv = hUSB->bufRecv; - bufRecv.insert(bufRecv.end(), appendData, appendData + dataSize); - int ret = RET_SUCCESS; - while (bufRecv.size() > sizeof(USBHead)) { - USBHead *usbHeader = (USBHead *)bufRecv.data(); - if (memcmp(usbHeader->flag, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { - WRITE_LOG(LOG_FATAL, "Error usb packet"); - ret = ERR_BUF_CHECK; - break; - } - if (bufRecv.size() < sizeof(USBHead) + usbHeader->dataSize) { - WRITE_LOG(LOG_DEBUG, "SendToHdcStream not enough"); - break; // successful , but not enough - } - if (usbHeader->sessionId != hSession->sessionId) { - // Only server do it here, daemon 'SendUsbSoftReset' no use - // hilog + ctrl^C to reproduction scene - // - // Because the USB-reset API does not work on all platforms, the last session IO data may be - // recveived, we need to ignore it. - if (hSession->serverOrDaemon && !hUSB->resetIO) { - WRITE_LOG(LOG_WARN, "SendToHdcStream sessionId not matched"); - SendUsbSoftReset(hUSB, usbHeader->sessionId); - hUSB->resetIO = true; - } - } else { - // usb data to logic - if (Base::SendToStream(stream, bufRecv.data() + sizeof(USBHead), usbHeader->dataSize) < 0) { - ret = ERR_IO_FAIL; - WRITE_LOG(LOG_FATAL, "Error usb send to stream"); - break; - } - } - bufRecv.erase(bufRecv.begin(), bufRecv.begin() + sizeof(USBHead) + usbHeader->dataSize); - } - return ret; -} -} \ No newline at end of file diff --git a/services/flashd/common/usb.h b/services/flashd/common/usb.h deleted file mode 100755 index 8b49c54c..00000000 --- a/services/flashd/common/usb.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_USB_H -#define HDC_USB_H -#include "common.h" - -namespace Hdc { -class HdcUSBBase { -public: - HdcUSBBase(const bool serverOrDaemonIn, void *ptrMainBase); - virtual ~HdcUSBBase(); - virtual int SendUSBRaw(HSession hSession, uint8_t *data, const int length) - { - return 0; - } - virtual bool ReadyForWorkThread(HSession hSession); - virtual void SendUsbSoftReset(HUSB hUSB, uint32_t sessionId) {}; - int SendUSBBlock(HSession hSession, uint8_t *data, const int length); - static void ReadUSB(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); - int SendToHdcStream(HSession hSession, uv_stream_t *stream, uint8_t *appendData, int dataSize); - -protected: - void *clsMainBase; - bool serverOrDaemon; - bool modRunning; -}; -} // namespace Hdc - -#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon.cpp b/services/flashd/daemon/daemon.cpp index fa34ef8b..fcf55dfa 100755 --- a/services/flashd/daemon/daemon.cpp +++ b/services/flashd/daemon/daemon.cpp @@ -13,9 +13,13 @@ * limitations under the License. */ #include "daemon.h" -#include "../common/serial_struct.h" + #include +#include "daemon_updater.h" +#include "flash_define.h" +#include "serial_struct.h" + namespace Hdc { HdcDaemon::HdcDaemon(bool serverOrDaemonIn) : HdcSessionBase(serverOrDaemonIn) @@ -91,13 +95,6 @@ void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB) enableSecure = (Base::Trim(secure) == "1"); } -void HdcDaemon::SendAndCloseChannel(HSession hSession, const uint32_t channelId, const std::string &info) -{ - Send(hSession->sessionId, channelId, CMD_KERNEL_ECHO_RAW, (uint8_t *)info.data(), info.size()); - uint8_t count = 1; - Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1); -} - // clang-format off #ifdef HDC_SUPPORT_FLASHD bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, @@ -122,7 +119,10 @@ bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uin ret = TaskCommandDispatch(hTaskInfo, TASK_UPDATER, command, payload, payloadSize); break; default: - SendAndCloseChannel(hSession, channelId, "Command not support in flashd\n"); + std::string info = "Command not support in flashd\n"; + Send(hSession->sessionId, channelId, CMD_KERNEL_ECHO_RAW, (uint8_t *)info.data(), info.size()); + uint8_t count = 1; + Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1); break; } return ret; @@ -131,55 +131,11 @@ bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uin bool HdcDaemon::RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, const int payloadSize) { - bool ret = true; - hTaskInfo->ownerSessionClass = this; - switch (command) { - case CMD_UNITY_EXECUTE: - case CMD_UNITY_REMOUNT: - case CMD_UNITY_REBOOT: - case CMD_UNITY_RUNMODE: - case CMD_UNITY_HILOG: - case CMD_UNITY_ROOTRUN: - case CMD_UNITY_TERMINATE: - case CMD_UNITY_BUGREPORT_INIT: - case CMD_UNITY_JPID: - ret = TaskCommandDispatch(hTaskInfo, TYPE_UNITY, command, payload, payloadSize); - break; - case CMD_SHELL_INIT: - case CMD_SHELL_DATA: - ret = TaskCommandDispatch(hTaskInfo, TYPE_SHELL, command, payload, payloadSize); - break; - case CMD_FILE_CHECK: - case CMD_FILE_DATA: - case CMD_FILE_FINISH: - case CMD_FILE_INIT: - case CMD_FILE_BEGIN: - ret = TaskCommandDispatch(hTaskInfo, TASK_FILE, command, payload, payloadSize); - break; - // One-way function, so fewer options - case CMD_APP_CHECK: - case CMD_APP_DATA: - case CMD_APP_UNINSTALL: - ret = TaskCommandDispatch(hTaskInfo, TASK_APP, command, payload, payloadSize); - break; - case CMD_FORWARD_INIT: - case CMD_FORWARD_CHECK: - case CMD_FORWARD_ACTIVE_SLAVE: - case CMD_FORWARD_DATA: - case CMD_FORWARD_FREE_CONTEXT: - case CMD_FORWARD_CHECK_RESULT: - ret = TaskCommandDispatch(hTaskInfo, TASK_FORWARD, command, payload, payloadSize); - break; - case CMD_UPDATER_CHECK: - case CMD_UPDATER_ERASE: - case CMD_UPDATER_FORMAT: - SendAndCloseChannel(hSession, channelId, "Command not support in hdcd\n"); - break; - default: - ret = false; - break; - } - return ret; + std::string info = "Command not support in hdcd\n"; + Send(hSession->sessionId, channelId, CMD_KERNEL_ECHO_RAW, (uint8_t *)info.data(), info.size()); + uint8_t count = 1; + Send(hSession->sessionId, channelId, CMD_KERNEL_CHANNEL_CLOSE, &count, 1); + return true; } // clang-format on #endif diff --git a/services/flashd/daemon/daemon.h b/services/flashd/daemon/daemon.h deleted file mode 100755 index 4eb7df29..00000000 --- a/services/flashd/daemon/daemon.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_DAEMON_H -#define HDC_DAEMON_H -#include "daemon_common.h" - -namespace Hdc { -class HdcDaemon : public HdcSessionBase { -public: - HdcDaemon(bool serverOrDaemonIn); - virtual ~HdcDaemon(); - void InitMod(bool bEnableTCP, bool bEnableUSB); - bool FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, - const int payloadSize); - bool ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command, uint8_t *bufPtr, - const int size); - void *clsTCPServ; - void *clsUSBServ; - void *clsJdwp; - -private: - bool RemoveInstanceTask(const uint8_t op, HTaskInfo hTask); - bool RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, const uint16_t command, - uint8_t *payload, const int payloadSize); - void SendAndCloseChannel(HSession hSession, const uint32_t channelId, const std::string &info); - void JdwpNewFileDescriptor(const uint8_t *buf, const int bytesIO); - bool HandDaemonAuth(HSession hSession, const uint32_t channelId, SessionHandShake &handshake); - void ClearInstanceResource(); - bool DaemonSessionHandshake(HSession hSession, const uint32_t channelId, uint8_t *payload, int payloadSize); - void TryStopInstance(); - - bool enableSecure; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon_app.cpp b/services/flashd/daemon/daemon_app.cpp deleted file mode 100755 index 4f04dc93..00000000 --- a/services/flashd/daemon/daemon_app.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "daemon_app.h" - -namespace Hdc { -HdcDaemonApp::HdcDaemonApp(HTaskInfo hTaskInfo) - : HdcTransferBase(hTaskInfo) -{ - commandBegin = CMD_APP_BEGIN; - commandData = CMD_APP_DATA; - funcAppModFinish = nullptr; -} - -HdcDaemonApp::~HdcDaemonApp() -{ - WRITE_LOG(LOG_DEBUG, "~HdcDaemonApp"); -} - -bool HdcDaemonApp::ReadyForRelease() -{ - if (!HdcTaskBase::ReadyForRelease()) { - return false; - } - if (!asyncCommand.ReadyForRelease()) { - return false; - } - return true; -} - -bool HdcDaemonApp::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) -{ - if (!HdcTransferBase::CommandDispatch(command, payload, payloadSize)) { - return false; - } - bool ret = true; - switch (command) { - case CMD_APP_CHECK: { - string tmpData = "/data/local/tmp/"; - string tmpSD = "/sdcard/tmp/"; - string dstPath = tmpData; - string bufString((char *)payload, payloadSize); - SerialStruct::ParseFromString(ctxNow.transferConfig, bufString); - // update transferconfig to main context - ctxNow.master = false; - ctxNow.fsOpenReq.data = &ctxNow; - // -lrtsdpg, -l -r -t -s.., - if (ctxNow.transferConfig.functionName == CMDSTR_APP_INSTALL - && ctxNow.transferConfig.options.find("s") != std::string::npos) { - dstPath = tmpSD; - } -#ifdef HDC_PCDEBUG - char tmpPath[256] = ""; - size_t size = 256; - uv_os_tmpdir(tmpPath, &size); - dstPath = tmpPath; - dstPath += Base::GetPathSep(); -#endif - dstPath += ctxNow.transferConfig.optionalName; - ctxNow.localPath = dstPath; - ctxNow.transferBegin = Base::GetRuntimeMSec(); - ctxNow.fileSize = ctxNow.transferConfig.fileSize; - ++refCount; - uv_fs_open(loopTask, &ctxNow.fsOpenReq, ctxNow.localPath.c_str(), - UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IRUSR, OnFileOpen); - break; - } - case CMD_APP_UNINSTALL: { - // This maybe has a command implanting risk, since it is a controllable device, it can be ignored - string bufString(reinterpret_cast(payload), payloadSize); - PackageShell(false, "", bufString); - break; - } - default: - break; - } - return ret; -}; - -bool HdcDaemonApp::AsyncInstallFinish(bool finish, int64_t exitStatus, const string result) -{ - if (mode == APPMOD_INSTALL) { - unlink(ctxNow.localPath.c_str()); - } - asyncCommand.DoRelease(); - string echo = result; - echo = Base::ReplaceAll(echo, "\n", " "); - vector vecBuf; - vecBuf.push_back(mode); - vecBuf.push_back(exitStatus == 0); - vecBuf.insert(vecBuf.end(), (uint8_t *)echo.c_str(), (uint8_t *)echo.c_str() + echo.size()); - SendToAnother(CMD_APP_FINISH, vecBuf.data(), vecBuf.size()); - --refCount; -#ifdef UNIT_TEST - Base::WriteBinFile((UT_TMP_PATH + "/appinstall.result").c_str(), (uint8_t *)MESSAGE_SUCCESS.c_str(), - MESSAGE_SUCCESS.size(), true); -#endif - return true; -} - -void HdcDaemonApp::PackageShell(bool installOrUninstall, const char *options, const string package) -{ - ++refCount; - // asynccmd Other processes, no RunningProtect protection - chmod(package.c_str(), 0644); // 0644 : permission - string doBuf; - if (installOrUninstall) { - doBuf = Base::StringFormat("bm install %s -p %s", options, package.c_str()); - } else { - doBuf = Base::StringFormat("bm uninstall %s -n %s", options, package.c_str()); - } - funcAppModFinish = std::bind(&HdcDaemonApp::AsyncInstallFinish, this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3); - if (installOrUninstall) { - mode = APPMOD_INSTALL; - } else { - mode = APPMOD_UNINSTALL; - } - asyncCommand.Initial(loopTask, funcAppModFinish); - asyncCommand.ExecuteCommand(doBuf); -} - -void HdcDaemonApp::Sideload(const char *pathOTA) -{ - mode = APPMOD_SIDELOAD; - LogMsg(MSG_OK, "[placeholders] sideload %s", pathOTA); - TaskFinish(); - unlink(pathOTA); -} - -void HdcDaemonApp::WhenTransferFinish(CtxFile *context) -{ - if (ctxNow.transferConfig.functionName == CMDSTR_APP_SIDELOAD) { - Sideload(context->localPath.c_str()); - } else if (ctxNow.transferConfig.functionName == CMDSTR_APP_INSTALL) { - PackageShell(true, context->transferConfig.options.c_str(), context->localPath.c_str()); - } else { - } -}; -} \ No newline at end of file diff --git a/services/flashd/daemon/daemon_app.h b/services/flashd/daemon/daemon_app.h deleted file mode 100755 index 7546fc39..00000000 --- a/services/flashd/daemon/daemon_app.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_DAEMON_APP_H -#define HDC_DAEMON_APP_H -#include "daemon_common.h" - -namespace Hdc { -class HdcDaemonApp : public HdcTransferBase { -public: - HdcDaemonApp(HTaskInfo hTaskInfo); - virtual ~HdcDaemonApp(); - bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); - bool ReadyForRelease(); - -private: - void WhenTransferFinish(CtxFile *context); - void PackageShell(bool installOrUninstall, const char *options, const string package); - bool AsyncInstallFinish(bool finish, int64_t exitStatus, const string result); - void Sideload(const char *pathOTA); - - AsyncCmd asyncCommand; - AsyncCmd::CmdResultCallback funcAppModFinish; - AppModType mode = APPMOD_NONE; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon_common.h b/services/flashd/daemon/daemon_common.h deleted file mode 100755 index 35786e03..00000000 --- a/services/flashd/daemon/daemon_common.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_DAEMON_COMMON_H -#define HDC_DAEMON_COMMON_H - -// clang-format off -#include "../common/common.h" -#include "../common/define.h" -#include "../common/file.h" -#include "../common/forward.h" -#include "../common/async_cmd.h" -#include "../common/serial_struct.h" -#include "jdwp.h" -#include "daemon.h" -#include "daemon_unity.h" -#include "daemon_tcp.h" -#include "daemon_app.h" -#include "daemon_usb.h" -#include "daemon_forward.h" -#ifdef HDC_SUPPORT_FLASHD -#include "daemon_updater.h" -#endif -#include "shell.h" - -// clang-format on - -namespace Hdc { -} -#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon_forward.cpp b/services/flashd/daemon/daemon_forward.cpp deleted file mode 100755 index 25ddb710..00000000 --- a/services/flashd/daemon/daemon_forward.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "daemon_forward.h" - -namespace Hdc { -HdcDaemonForward::HdcDaemonForward(HTaskInfo hTaskInfo) - : HdcForwardBase(hTaskInfo) -{ -} - -HdcDaemonForward::~HdcDaemonForward() -{ -} - -void HdcDaemonForward::SetupJdwpPointCallBack(uv_idle_t *handle) -{ - HCtxForward ctxPoint = (HCtxForward)handle->data; - HdcDaemonForward *thisClass = reinterpret_cast(ctxPoint->thisClass); - thisClass->SetupPointContinue(ctxPoint, 1); // It usually works - Base::TryCloseHandle((const uv_handle_t *)handle, Base::CloseIdleCallback); - WRITE_LOG(LOG_DEBUG, "Setup JdwpPointCallBack finish"); - --thisClass->refCount; - return; -} - -bool HdcDaemonForward::SetupJdwpPoint(HCtxForward ctxPoint) -{ - HdcDaemon *daemon = (HdcDaemon *)taskInfo->ownerSessionClass; - HdcJdwp *clsJdwp = (HdcJdwp *)daemon->clsJdwp; - uint32_t pid = std::stol(ctxPoint->localArgs[1]); - if (ctxPoint->checkPoint) { // checke - bool ret = clsJdwp->CheckPIDExist(pid); - SetupPointContinue(ctxPoint, (int)ret); - WRITE_LOG(LOG_DEBUG, "Jdwp jump checkpoint"); - return true; - } - // do slave connect - // fd[0] for forward, fd[1] for jdwp - // forward to close fd[0], fd[1] for jdwp close - int fds[2] = { 0 }; - bool ret = false; - Base::CreateSocketPair(fds); - if (uv_tcp_init(loopTask, &ctxPoint->tcp)) { - return ret; - } - ctxPoint->tcp.data = ctxPoint; - if (uv_tcp_open(&ctxPoint->tcp, fds[0])) { - return ret; - } - constexpr auto len = sizeof(uint32_t); - uint8_t flag[1 + len + len]; - flag[0] = SP_JDWP_NEWFD; - if (memcpy_s(flag + 1, sizeof(flag) - 1, &pid, len) || - memcpy_s(flag + 1 + len, sizeof(flag) - len - 1, &fds[1], len)) { - return ret; - } - if (ThreadCtrlCommunicate(flag, sizeof(flag)) > 0) { - ret = true; - } - WRITE_LOG(LOG_DEBUG, "SendJdwpNewFD Finish,ret:%d fd0:%d fd1:%d", ret, fds[0], fds[1]); - if (!ret) { - Base::CloseSocketPair(fds); - return ret; - } - - ++refCount; - Base::IdleUvTask(loopTask, ctxPoint, SetupJdwpPointCallBack); - return ret; -} -} \ No newline at end of file diff --git a/services/flashd/daemon/daemon_forward.h b/services/flashd/daemon/daemon_forward.h deleted file mode 100755 index 5dfae60a..00000000 --- a/services/flashd/daemon/daemon_forward.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_DAEMON_FORWARD_H -#define HDC_DAEMON_FORWARD_H -#include "daemon_common.h" - -namespace Hdc { -class HdcDaemonForward : public HdcForwardBase { -public: - HdcDaemonForward(HTaskInfo hTaskInfo); - virtual ~HdcDaemonForward(); - -private: - bool SetupJdwpPoint(HCtxForward ctxPoint); - static void SetupJdwpPointCallBack(uv_idle_t *handle); -}; -} // namespace Hdc - -#endif \ No newline at end of file diff --git a/services/flashd/daemon/daemon_tcp.cpp b/services/flashd/daemon/daemon_tcp.cpp deleted file mode 100755 index 64d16aeb..00000000 --- a/services/flashd/daemon/daemon_tcp.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "daemon_tcp.h" - -namespace Hdc { -HdcDaemonTCP::HdcDaemonTCP(const bool serverOrDaemonIn, void *ptrMainBase) - : HdcTCPBase(serverOrDaemonIn, ptrMainBase) -{ - // If the listening value for the property setting is obtained, it will be 0 randomly assigned. - char strTCPPort[BUF_SIZE_TINY] = ""; - const uint16_t BUFF_SIZE = 8; - Base::GetHdcProperty("persist.hdc.port", strTCPPort, BUFF_SIZE); - tcpListenPort = atoi(strTCPPort); - if (tcpListenPort <= 0) { - tcpListenPort = 10178; // 10178 def port - } - Base::ZeroStruct(servUDP); - Base::ZeroStruct(servTCP); -#ifdef HDC_DEBUG - const uint16_t DEBUG_TCP_PORT = 10178; - tcpListenPort = DEBUG_TCP_PORT; -#endif -} - -HdcDaemonTCP::~HdcDaemonTCP() -{ -} - -void HdcDaemonTCP::Stop() -{ - Base::TryCloseHandle((const uv_handle_t *)&servUDP); - Base::TryCloseHandle((const uv_handle_t *)&servTCP); - WRITE_LOG(LOG_DEBUG, "~HdcDaemonTCP"); -} - -void HdcDaemonTCP::TransmitConfig(const sockaddr *addrSrc, uv_udp_t *handle) -{ - char srcIP[BUF_SIZE_TINY] = ""; - struct sockaddr addrSrcIPPort; - uv_udp_send_t *req = new uv_udp_send_t(); - if (!req) { - return; - } - string sendBuf = Base::StringFormat("%s-%d", HANDSHAKE_MESSAGE.c_str(), tcpListenPort); - uv_buf_t sndbuf = uv_buf_init((char *)sendBuf.c_str(), sendBuf.size()); - uv_ip4_name((sockaddr_in *)addrSrc, srcIP, sizeof(srcIP)); - uv_ip4_addr(srcIP, DEFAULT_PORT, (sockaddr_in *)&addrSrcIPPort); - uv_udp_send(req, handle, &sndbuf, 1, &addrSrcIPPort, SendUDPFinish); -} - -void HdcDaemonTCP::AcceptClient(uv_stream_t *server, int status) -{ - uv_loop_t *ptrLoop = server->loop; - uv_tcp_t *pServTCP = (uv_tcp_t *)server; - HdcDaemonTCP *thisClass = (HdcDaemonTCP *)pServTCP->data; - HdcSessionBase *ptrConnect = (HdcSessionBase *)thisClass->clsMainBase; - HdcSessionBase *daemon = reinterpret_cast(thisClass->clsMainBase); - const uint16_t maxWaitTime = UV_DEFAULT_INTERVAL; - auto ctrl = daemon->BuildCtrlString(SP_START_SESSION, 0, nullptr, 0); - HSession hSession = ptrConnect->MallocSession(false, CONN_TCP, thisClass); - if (!hSession) { - return; - } - if (uv_accept(server, (uv_stream_t *)&hSession->hWorkTCP) < 0) { - goto Finish; - } - if ((hSession->fdChildWorkTCP = Base::DuplicateUvSocket(&hSession->hWorkTCP)) < 0) { - goto Finish; - }; - Base::TryCloseHandle((uv_handle_t *)&hSession->hWorkTCP); - Base::StartWorkThread(ptrLoop, ptrConnect->SessionWorkThread, Base::FinishWorkThread, hSession); - // wait for thread up - while (hSession->childLoop.active_handles == 0) { - usleep(maxWaitTime); - } - Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); - return; -Finish: - ptrConnect->FreeSession(hSession->sessionId); -} - -void HdcDaemonTCP::RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf) -{ - TransmitConfig(addrSrc, handle); -} - -void HdcDaemonTCP::SetUDPListen() -{ - struct sockaddr_in addr; - int r; - HdcSessionBase *ptrConnect = (HdcSessionBase *)clsMainBase; - // udp broadcast - servUDP.data = this; - r = uv_udp_init(&ptrConnect->loopMain, &servUDP); - r = uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr); - r = uv_udp_bind(&servUDP, (const struct sockaddr *)&addr, UV_UDP_REUSEADDR); - r = uv_udp_recv_start(&servUDP, AllocStreamUDP, RecvUDP); -} - -// Set the daemon-side TCP listening -int HdcDaemonTCP::SetTCPListen() -{ - // tcp listen - HdcSessionBase *ptrConnect = (HdcSessionBase *)clsMainBase; - servTCP.data = this; - struct sockaddr_in addr; - int namelen; - const int DEFAULT_BACKLOG = 128; - - uv_tcp_init(&ptrConnect->loopMain, &servTCP); - uv_ip4_addr("0.0.0.0", tcpListenPort, &addr); // tcpListenPort == 0 - uv_tcp_bind(&servTCP, (const struct sockaddr *)&addr, 0); - if (uv_listen((uv_stream_t *)&servTCP, DEFAULT_BACKLOG, (uv_connection_cb)AcceptClient)) { - return ERR_API_FAIL; - } - // Get listen port - Base::ZeroStruct(addr); - namelen = sizeof(addr); - if (uv_tcp_getsockname(&servTCP, (sockaddr *)&addr, &namelen)) { - return ERR_API_FAIL; - } - tcpListenPort = ntohs(addr.sin_port); - return RET_SUCCESS; -} - -int HdcDaemonTCP::Initial() -{ - WRITE_LOG(LOG_DEBUG, "HdcDaemonTCP init"); - SetUDPListen(); - if (SetTCPListen() != RET_SUCCESS) { - WRITE_LOG(LOG_FATAL, "TCP listen failed"); - return ERR_GENERIC; - } -#ifndef UNIT_TEST - WRITE_LOG(LOG_INFO, "TCP listen on port:[%d]", tcpListenPort); -#endif - return RET_SUCCESS; -} -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/daemon/daemon_tcp.h b/services/flashd/daemon/daemon_tcp.h deleted file mode 100755 index bd399ea6..00000000 --- a/services/flashd/daemon/daemon_tcp.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_DAEMON_TCP_H -#define HDC_DAEMON_TCP_H -#include "daemon_common.h" - -namespace Hdc { -class HdcDaemonTCP : public HdcTCPBase { -public: - HdcDaemonTCP(const bool serverOrDaemonIn, void *ptrMainBase); - virtual ~HdcDaemonTCP(); - void RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf); - uint16_t tcpListenPort; - int Initial(); - void Stop(); - -private: - static void AcceptClient(uv_stream_t *server, int status); - void TransmitConfig(const sockaddr *addrSrc, uv_udp_t *handle); - int SetTCPListen(); - void SetUDPListen(); - - uv_tcp_t servTCP; - uv_udp_t servUDP; -}; -} // namespace Hdc - -#endif diff --git a/services/flashd/daemon/daemon_unity.h b/services/flashd/daemon/daemon_unity.h deleted file mode 100755 index c816487f..00000000 --- a/services/flashd/daemon/daemon_unity.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_DAEMON_UNITY_H -#define HDC_DAEMON_UNITY_H -#include "daemon_common.h" - -namespace Hdc { -class HdcDaemonUnity : public HdcTaskBase { -public: - HdcDaemonUnity(HTaskInfo hTaskInfo); - virtual ~HdcDaemonUnity(); - bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); - void StopTask(); - bool ReadyForRelease(); - -private: - static void OnFdRead(uv_fs_t *req); - int ExecuteShell(const char *shellCommand); - bool FindMountDeviceByPath(const char *toQuery, char *dev); - bool RemountPartition(const char *dir); - bool RemountDevice(); - bool RebootDevice(const string &cmd); - bool SetDeviceRunMode(void *daemonIn, const char *cmd); - bool GetHiLog(const char *cmd); - bool ListJdwpProcess(void *daemonIn); - bool AsyncCmdOut(bool finish, int64_t exitStatus, const string result); - - const string rebootProperty = "sys.powerctl"; - AsyncCmd asyncCommand; - uint16_t currentDataCommand; -#ifdef UNIT_TEST - int countUt = 0; -#endif -}; -} // namespace Hdc -#endif // HDC_DAEMON_UNITY_H diff --git a/services/flashd/daemon/daemon_updater.cpp b/services/flashd/daemon/daemon_updater.cpp index 1cd520b7..2e84fe75 100755 --- a/services/flashd/daemon/daemon_updater.cpp +++ b/services/flashd/daemon/daemon_updater.cpp @@ -16,6 +16,7 @@ #include "daemon_common.h" #include "flashd/flashd.h" #include "flash_utils.h" +#include "flash_define.h" namespace Hdc { DaemonUpdater::DaemonUpdater(HTaskInfo hTaskInfo) : HdcTransferBase(hTaskInfo) @@ -46,6 +47,7 @@ bool DaemonUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, co } switch (command) { case CMD_UPDATER_DATA: { + const uint8_t payloadPrefixReserve = 64; string serialStrring((char *)payload, payloadPrefixReserve); TransferPayload pld {}; SerialStruct::ParseFromString(pld, serialStrring); diff --git a/services/flashd/daemon/daemon_usb.cpp b/services/flashd/daemon/daemon_usb.cpp deleted file mode 100755 index 6f5a33b6..00000000 --- a/services/flashd/daemon/daemon_usb.cpp +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "daemon_usb.h" -#include "usb_ffs.h" - -namespace Hdc { -HdcDaemonUSB::HdcDaemonUSB(const bool serverOrDaemonIn, void *ptrMainBase) - : HdcUSBBase(serverOrDaemonIn, ptrMainBase) -{ - Base::ZeroStruct(sendEP); - Base::ZeroStruct(usbHandle); - uv_mutex_init(&sendEP); -} - -HdcDaemonUSB::~HdcDaemonUSB() -{ - // Closed in the IO loop, no longer closing CLOSE ENDPOINT - uv_mutex_destroy(&sendEP); - if (controlEp > 0) { - close(controlEp); - } -} - -void HdcDaemonUSB::Stop() -{ - WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB Stop"); - // Here only clean up the IO-related resources, session related resources clear reason to clean up the session - // module - modRunning = false; - WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB Stop free main session"); - Base::TryCloseHandle((uv_handle_t *)&checkEP); - CloseEndpoint(&usbHandle); - WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB Stop free main session finish"); -} - -string HdcDaemonUSB::GetDevPath(const std::string &path) -{ - DIR *dir = ::opendir(path.c_str()); - if (dir == nullptr) { - WRITE_LOG(LOG_WARN, "%s: cannot open devpath: errno: %d", path.c_str(), errno); - return ""; - } - - string res = USB_FFS_BASE; - string node; - int count = 0; - struct dirent *entry = nullptr; - while ((entry = ::readdir(dir))) { - if (*entry->d_name == '.') { - continue; - } - node = entry->d_name; - ++count; - } - if (count > 1) { - res += "hdc"; - } else { - res += node; - } - ::closedir(dir); - return res; -} - -int HdcDaemonUSB::Initial() -{ - // after Linux-3.8,kernel switch to the USB Function FS - // Implement USB hdc function in user space - WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB init"); - basePath = GetDevPath(USB_FFS_BASE); - if (access((basePath + "/ep0").c_str(), F_OK) != 0) { - WRITE_LOG(LOG_DEBUG, "Only support usb-ffs, make sure kernel3.8+ and usb-ffs enabled, usbmode disabled"); - return -1; - } - HdcDaemon *daemon = (HdcDaemon *)clsMainBase; - WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB::Initiall"); - uv_timer_init(&daemon->loopMain, &checkEP); - checkEP.data = this; - uv_timer_start(&checkEP, WatchEPTimer, 0, TIME_BASE); - return 0; -} - -// DAEMON end USB module USB-FFS EP port connection -int HdcDaemonUSB::ConnectEPPoint(HUSB hUSB) -{ - int ret = ERR_GENERIC; - while (true) { - if (controlEp <= 0) { - // After the control port sends the instruction, the device is initialized by the device to the HOST host, - // which can be found for USB devices. Do not send initialization to the EP0 control port, the USB - // device will not be initialized by Host - WRITE_LOG(LOG_DEBUG, "Begin send to control(EP0) for usb descriptor init"); - string ep0Path = basePath + "/ep0"; - if ((controlEp = open(ep0Path.c_str(), O_RDWR)) < 0) { - WRITE_LOG(LOG_WARN, "%s: cannot open control endpoint: errno=%d", ep0Path.c_str(), errno); - break; - } - if (write(controlEp, &USB_FFS_DESC, sizeof(USB_FFS_DESC)) < 0) { - WRITE_LOG(LOG_WARN, "%s: write ffs configs failed: errno=%d", ep0Path.c_str(), errno); - break; - } - if (write(controlEp, &USB_FFS_VALUE, sizeof(USB_FFS_VALUE)) < 0) { - WRITE_LOG(LOG_WARN, "%s: write USB_FFS_VALUE failed: errno=%d", ep0Path.c_str(), errno); - break; - } - // active usbrc,Send USB initialization singal - Base::SetHdcProperty("sys.usb.ffs.ready", "1"); - WRITE_LOG(LOG_DEBUG, "ConnectEPPoint ctrl init finish, set usb-ffs ready"); - } - string outPath = basePath + "/ep1"; - if ((hUSB->bulkOut = open(outPath.c_str(), O_RDWR)) < 0) { - WRITE_LOG(LOG_WARN, "%s: cannot open bulk-out ep: errno=%d", outPath.c_str(), errno); - break; - } - string inPath = basePath + "/ep2"; - if ((hUSB->bulkIn = open(inPath.c_str(), O_RDWR)) < 0) { - WRITE_LOG(LOG_WARN, "%s: cannot open bulk-in ep: errno=%d", inPath.c_str(), errno); - break; - } - // cannot open with O_CLOEXEC, must fcntl - fcntl(controlEp, F_SETFD, FD_CLOEXEC); - fcntl(hUSB->bulkOut, F_SETFD, FD_CLOEXEC); - fcntl(hUSB->bulkIn, F_SETFD, FD_CLOEXEC); - - WRITE_LOG(LOG_DEBUG, "New bulk in\\out open bulkout:%d bulkin:%d", hUSB->bulkOut, hUSB->bulkIn); - hUSB->bufRecv.clear(); - ret = RET_SUCCESS; - break; - } - if (ret != RET_SUCCESS) { - CloseEndpoint(hUSB, true); - } - return ret; -} - -void HdcDaemonUSB::CloseEndpoint(HUSB hUSB, bool closeCtrlEp) -{ - if (hUSB->bulkIn > 0) { - close(hUSB->bulkIn); - hUSB->bulkIn = 0; - } - if (hUSB->bulkOut > 0) { - close(hUSB->bulkOut); - hUSB->bulkOut = 0; - } - if (controlEp > 0 && closeCtrlEp) { - close(controlEp); - controlEp = 0; - } - isAlive = false; - WRITE_LOG(LOG_FATAL, "DaemonUSB close endpoint"); -} - -void HdcDaemonUSB::ResetOldSession(const uint32_t sessionId) -{ - HdcDaemon *daemon = reinterpret_cast(clsMainBase); - HSession hSession = daemon->AdminSession(OP_QUERY, sessionId, nullptr); - if (hSession == nullptr) { - return; - } - hSession->hUSB->resetIO = true; - // The Host side is restarted, but the USB cable is still connected - WRITE_LOG(LOG_WARN, "Hostside softreset to restart daemon, old sessionId:%u", sessionId); - daemon->PushAsyncMessage(sessionId, ASYNC_FREE_SESSION, nullptr, 0); -} - -// Prevent other USB data misfortunes to send the program crash -int HdcDaemonUSB::AvailablePacket(uint8_t *ioBuf, uint32_t *sessionId) -{ - int ret = RET_SUCCESS; - constexpr auto maxBufFactor = 1.2; - while (true) { - struct USBHead *usbPayloadHeader = (struct USBHead *)ioBuf; - if (memcmp(usbPayloadHeader->flag, PACKET_FLAG.c_str(), PACKET_FLAG.size())) { - ret = ERR_BUF_CHECK; - break; - } - if (usbPayloadHeader->dataSize > MAX_SIZE_IOBUF * maxBufFactor + sizeof(USBHead)) { - ret = ERR_BUF_SIZE; - break; - } - if ((usbPayloadHeader->option & USB_OPTION_RESET)) { - ResetOldSession(usbPayloadHeader->sessionId); - ret = ERR_IO_SOFT_RESET; - break; - } - *sessionId = usbPayloadHeader->sessionId; - break; - } - return ret; -} - -// Work in subcrete,Work thread is ready -bool HdcDaemonUSB::ReadyForWorkThread(HSession hSession) -{ - HdcUSBBase::ReadyForWorkThread(hSession); - return true; -}; - -int HdcDaemonUSB::CloseBulkEp(bool bulkInOut, int bulkFd, uv_loop_t *loop) -{ - struct CtxCloseBulkEp { - uv_fs_t req; - HdcDaemonUSB *thisClass; - bool bulkInOut; - }; - CtxCloseBulkEp *ctx = new CtxCloseBulkEp(); - uv_fs_t *req = &ctx->req; - req->data = ctx; - ctx->bulkInOut = bulkInOut; - ctx->thisClass = this; - isAlive = false; - uv_fs_close(loop, req, bulkFd, [](uv_fs_t *req) { - auto ctx = (CtxCloseBulkEp *)req->data; - if (ctx->bulkInOut) { - ctx->thisClass->usbHandle.bulkIn = 0; - } else { - ctx->thisClass->usbHandle.bulkOut = 0; - } - WRITE_LOG(LOG_DEBUG, "Try to abort blukin write callback %s", ctx->bulkInOut ? "bulkin" : "bulkout"); - uv_fs_req_cleanup(req); - delete ctx; - }); - return 0; -} - -int HdcDaemonUSB::SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t *data, const int length) -{ - int bulkIn = hMainUSB->bulkIn; - int childRet = 0; - int ret = ERR_IO_FAIL; - int offset = 0; - while (modRunning && isAlive && !hSession->isDead && !hSession->hUSB->resetIO) { - childRet = write(bulkIn, (uint8_t *)data + offset, length - offset); - if (childRet <= 0) { - int err = errno; - if (err == EINTR) { - WRITE_LOG(LOG_DEBUG, "BulkinWrite write EINTR, try again"); - continue; - } else { - WRITE_LOG(LOG_FATAL, "BulkinWrite write fatal errno %d", err); - isAlive = false; - } - break; - } - offset += childRet; - if (offset >= length) { - break; - } - } - if (offset == length) { - ret = length; - } else { - WRITE_LOG(LOG_FATAL, - "BulkinWrite write failed, nsize:%d really:%d modRunning:%d isAlive:%d SessionDead:%d usbReset:%d", - length, offset, modRunning, isAlive, hSession->isDead, hSession->hUSB->resetIO); - } - USBHead *pUSBHead = (USBHead *)data; - if ((pUSBHead->option & USB_OPTION_TAIL) || ret < 0) { - // tail or failed, dec Ref - hSession->sendRef--; - } - return ret; -} - -int HdcDaemonUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) -{ - HdcDaemon *daemon = (HdcDaemon *)hSession->classInstance; - // Prevent memory stacking, send temporary way to use asynchronous - // Generally sent in the same thread, but when new session is created, there is a possibility that the old session - // is not retired. - // At present, the radical transmission method is currently opened directly in various threads, and - // it can be used exclusive File-DESC transmission mode in each thread. The late stage can be used as asynchronous + - // SendPipe to the main thread transmission. - uv_mutex_lock(&sendEP); - int ret = SendUSBIOSync(hSession, &usbHandle, data, length); - if (ret < 0) { - daemon->FreeSession(hSession->sessionId); - WRITE_LOG(LOG_DEBUG, "SendUSBRaw try to freesession"); - } - uv_mutex_unlock(&sendEP); - return ret; -} - -// cross thread call -void HdcDaemonUSB::OnNewHandshakeOK(const uint32_t sessionId) -{ - currentSessionId = sessionId; // real Id -} - -HSession HdcDaemonUSB::PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, int recvBytesIO) -{ - HdcDaemon *daemon = reinterpret_cast(clsMainBase); - HSession hChildSession = daemon->MallocSession(false, CONN_USB, this, sessionId); - if (!hChildSession) { - return nullptr; - } - if (currentSessionId != 0) { - // reset old session - // The Host side is restarted, but the USB cable is still connected - WRITE_LOG(LOG_WARN, "New session coming, restart old sessionId:%u", currentSessionId); - daemon->PushAsyncMessage(currentSessionId, ASYNC_FREE_SESSION, nullptr, 0); - } - Base::StartWorkThread(&daemon->loopMain, daemon->SessionWorkThread, Base::FinishWorkThread, hChildSession); - auto funcNewSessionUp = [](uv_timer_t *handle) -> void { - HSession hChildSession = reinterpret_cast(handle->data); - HdcDaemon *daemon = reinterpret_cast(hChildSession->classInstance); - if (hChildSession->childLoop.active_handles == 0) { - return; - } - if (!hChildSession->isDead) { - auto ctrl = daemon->BuildCtrlString(SP_START_SESSION, 0, nullptr, 0); - Base::SendToStream((uv_stream_t *)&hChildSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); - WRITE_LOG(LOG_DEBUG, "Main thread usbio mirgate finish"); - } - Base::TryCloseHandle(reinterpret_cast(handle), Base::CloseTimerCallback); - }; - Base::TimerUvTask(&daemon->loopMain, hChildSession, funcNewSessionUp); - return hChildSession; -} - -int HdcDaemonUSB::DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBuf, int readBytes) -{ - // Format:USBPacket1 payload1...USBPacketn - // payloadn-[USBHead1(PayloadHead1+Payload1)]+[USBHead2(Payload2)]+...+[USBHeadN(PayloadN)] - HSession hChildSession = nullptr; - HdcDaemon *daemon = reinterpret_cast(clsMainBase); - hChildSession = daemon->AdminSession(OP_QUERY, sessionId, nullptr); - if (!hChildSession) { - hChildSession = PrepareNewSession(sessionId, readBuf, readBytes); - if (!hChildSession) { - return ERR_SESSION_NOFOUND; - } - } - if (hChildSession->childCleared) { - return ERR_SESSION_DEAD; - } - if (SendToHdcStream(hChildSession, reinterpret_cast(&hChildSession->dataPipe[STREAM_MAIN]), readBuf, - readBytes) - != RET_SUCCESS) { - return ERR_IO_FAIL; - } - return readBytes; -} - -bool HdcDaemonUSB::JumpAntiquePacket(const uint8_t &buf, ssize_t bytes) const -{ - constexpr size_t antiqueFlagSize = 4; - constexpr size_t antiqueFullSize = 24; - // anti CNXN 0x4e584e43 - uint8_t flag[] = { 0x43, 0x4e, 0x58, 0x4e }; - if (bytes == antiqueFullSize && !memcmp(&buf, flag, antiqueFlagSize)) { - return true; - } - return false; -} - -// Only physically swap EP ports will be reset -void HdcDaemonUSB::OnUSBRead(uv_fs_t *req) -{ // Only read at the main thread - auto ctxIo = reinterpret_cast(req->data); - auto hUSB = reinterpret_cast(ctxIo->data); - auto thisClass = reinterpret_cast(ctxIo->thisClass); - uint8_t *bufPtr = ctxIo->buf; - ssize_t bytesIOBytes = req->result; - uint32_t sessionId = 0; - bool ret = false; - int childRet = 0; - --thisClass->ref; - while (thisClass->isAlive) { - // Don't care is module running, first deal with this - if (bytesIOBytes < 0) { - WRITE_LOG(LOG_WARN, "USBIO failed1 %s", uv_strerror(bytesIOBytes)); - break; - } else if (bytesIOBytes == 0) { - // zero packet - ret = true; - break; - } - if (thisClass->JumpAntiquePacket(*bufPtr, bytesIOBytes)) { - WRITE_LOG(LOG_DEBUG, "JumpAntiquePacket auto jump"); - ret = true; - break; - } - // guess is head of packet - if ((childRet = thisClass->AvailablePacket((uint8_t *)bufPtr, &sessionId)) != RET_SUCCESS) { - if (childRet != ERR_IO_SOFT_RESET) { - WRITE_LOG(LOG_WARN, "AvailablePacket check failed, ret:%d buf:%-50s", bytesIOBytes, bufPtr); - break; - } - // reset packet - } else { - // AvailablePacket case - if (thisClass->DispatchToWorkThread(sessionId, bufPtr, bytesIOBytes) < 0) { - WRITE_LOG(LOG_FATAL, "DispatchToWorkThread failed"); - break; - } - } - if (thisClass->LoopUSBRead(hUSB) < 0) { - WRITE_LOG(LOG_FATAL, "LoopUSBRead failed"); - break; - } - ret = true; - break; - } - if (!ret) { - thisClass->isAlive = false; - } - delete[] ctxIo->buf; - uv_fs_req_cleanup(req); - delete ctxIo; -} - -int HdcDaemonUSB::LoopUSBRead(HUSB hUSB) -{ - int ret = -1; - HdcDaemon *daemon = reinterpret_cast(clsMainBase); - // must > available size, or it will be incorrect - int readMax = Base::GetMaxBufSize() + sizeof(USBHead) + EXTRA_ALLOC_SIZE; - auto ctxIo = new CtxUvFileCommonIo(); - auto buf = new uint8_t[readMax](); - uv_fs_t *req = nullptr; - uv_buf_t iov; - if (ctxIo == nullptr || buf == nullptr) { - goto FAILED; - } - ctxIo->buf = buf; - ctxIo->bufSize = readMax; - ctxIo->data = hUSB; - ctxIo->thisClass = this; - req = &ctxIo->req; - req->data = ctxIo; - iov = uv_buf_init(reinterpret_cast(ctxIo->buf), ctxIo->bufSize); - ret = uv_fs_read(&daemon->loopMain, req, hUSB->bulkOut, &iov, 1, -1, OnUSBRead); - if (ret < 0) { - WRITE_LOG(LOG_FATAL, "uv_fs_read < 0"); - goto FAILED; - } - ++this->ref; - return 0; -FAILED: - if (ctxIo != nullptr) { - delete ctxIo; - } - if (buf != nullptr) { - delete[] buf; - } - return -1; -} - -// Because USB can connect to only one host,daemonUSB is only one Session by default -void HdcDaemonUSB::WatchEPTimer(uv_timer_t *handle) -{ - HdcDaemonUSB *thisClass = (HdcDaemonUSB *)handle->data; - HUSB hUSB = &thisClass->usbHandle; - HdcDaemon *daemon = reinterpret_cast(thisClass->clsMainBase); - if (thisClass->isAlive || thisClass->ref > 0) { - return; - } - bool resetEp = false; - do { - if (hUSB->bulkIn > 0) { - thisClass->CloseBulkEp(true, thisClass->usbHandle.bulkIn, &daemon->loopMain); - resetEp = true; - } - if (hUSB->bulkOut > 0) { - thisClass->CloseBulkEp(false, thisClass->usbHandle.bulkOut, &daemon->loopMain); - resetEp = true; - } - if (thisClass->controlEp > 0) { - close(thisClass->controlEp); - thisClass->controlEp = 0; - resetEp = true; - } - } while (false); - if (resetEp || thisClass->usbHandle.bulkIn != 0 || thisClass->usbHandle.bulkOut != 0) { - return; - } - // until all bulkport reset - if (thisClass->ConnectEPPoint(hUSB) != RET_SUCCESS) { - return; - } - // connect OK - thisClass->isAlive = true; - thisClass->LoopUSBRead(hUSB); -} -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/daemon/daemon_usb.h b/services/flashd/daemon/daemon_usb.h deleted file mode 100755 index 38dc5244..00000000 --- a/services/flashd/daemon/daemon_usb.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_DAEMON_USB_H -#define HDC_DAEMON_USB_H -#include "daemon_common.h" - -namespace Hdc { -class HdcDaemonUSB : public HdcUSBBase { -public: - HdcDaemonUSB(const bool serverOrDaemonIn, void *ptrMainBase); - virtual ~HdcDaemonUSB(); - int Initial(); - void Stop(); - int SendUSBRaw(HSession hSession, uint8_t *data, const int length); - void OnNewHandshakeOK(const uint32_t sessionId); - -private: - struct CtxUvFileCommonIo { - uv_fs_t req; - uint8_t *buf; - int bufSize; - void *thisClass; - void *data; - }; - static void OnUSBRead(uv_fs_t *req); - static void WatchEPTimer(uv_timer_t *handle); - int ConnectEPPoint(HUSB hUSB); - int DispatchToWorkThread(const uint32_t sessionId, uint8_t *readBuf, int readBytes); - int AvailablePacket(uint8_t *ioBuf, uint32_t *sessionId); - void CloseEndpoint(HUSB hUSB, bool closeCtrlEp = false); - string GetDevPath(const std::string &path); - bool ReadyForWorkThread(HSession hSession); - int LoopUSBRead(HUSB hUSB); - HSession PrepareNewSession(uint32_t sessionId, uint8_t *pRecvBuf, int recvBytesIO); - bool JumpAntiquePacket(const uint8_t &buf, ssize_t bytes) const; - int SendUSBIOSync(HSession hSession, HUSB hMainUSB, const uint8_t *data, const int length); - int CloseBulkEp(bool bulkInOut, int bulkFd, uv_loop_t *loop); - void ResetOldSession(const uint32_t sessionId); - - HdcUSB usbHandle; - string basePath; // usb device's base path - uint32_t currentSessionId = 0; // USB mode,limit only one session - std::atomic ref = 0; - uv_timer_t checkEP; // server-use - uv_mutex_t sendEP; - bool isAlive = false; - int controlEp = 0; // EP0 -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/daemon/flashd_main.cpp b/services/flashd/daemon/flashd_main.cpp index 56e801b8..f5270bc2 100755 --- a/services/flashd/daemon/flashd_main.cpp +++ b/services/flashd/daemon/flashd_main.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "daemon_common.h" +#include "daemon_updater.h" #include "flashd/flashd.h" #include "updater/updater.h" diff --git a/services/flashd/daemon/jdwp.cpp b/services/flashd/daemon/jdwp.cpp deleted file mode 100755 index 7a3b1526..00000000 --- a/services/flashd/daemon/jdwp.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "jdwp.h" - -namespace Hdc { -HdcJdwp::HdcJdwp(uv_loop_t *loopIn) -{ - Base::ZeroStruct(listenPipe); - listenPipe.data = this; - loop = loopIn; - refCount = 0; - uv_rwlock_init(&lockMapContext); -} - -HdcJdwp::~HdcJdwp() -{ - uv_rwlock_destroy(&lockMapContext); -} - -bool HdcJdwp::ReadyForRelease() -{ - return refCount == 0; -} - -void HdcJdwp::Stop() -{ - auto funcListenPipeClose = [](uv_handle_t *handle) -> void { - HdcJdwp *thisClass = (HdcJdwp *)handle->data; - --thisClass->refCount; - }; - Base::TryCloseHandle((const uv_handle_t *)&listenPipe, funcListenPipeClose); - for (auto &&obj : mapCtxJdwp) { - HCtxJdwp v = obj.second; - FreeContext(v); - } - AdminContext(OP_CLEAR, 0, nullptr); -} - -void *HdcJdwp::MallocContext() -{ - HCtxJdwp ctx = nullptr; - if ((ctx = new ContextJdwp()) == nullptr) { - return nullptr; - } - ctx->thisClass = this; - ctx->pipe.data = ctx; - ++refCount; - return ctx; -} - -// Single thread, two parameters can be used -void HdcJdwp::FreeContext(HCtxJdwp ctx) -{ - if (ctx->finish) { - return; - } - Base::TryCloseHandle((const uv_handle_t *)&ctx->pipe); - ctx->finish = true; - AdminContext(OP_REMOVE, ctx->pid, nullptr); - auto funcReqClose = [](uv_idle_t *handle) -> void { - HCtxJdwp ctx = (HCtxJdwp)handle->data; - --ctx->thisClass->refCount; - Base::TryCloseHandle((uv_handle_t *)handle, Base::CloseIdleCallback); - delete ctx; - }; - Base::IdleUvTask(loop, ctx, funcReqClose); -} - -void HdcJdwp::ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf) -{ - bool ret = true; - HCtxJdwp ctxJdwp = (HCtxJdwp)pipe->data; - HdcJdwp *thisClass = (HdcJdwp *)ctxJdwp->thisClass; - char *p = ctxJdwp->buf; - uint32_t pid = 0; - - if (nread == UV_ENOBUFS) { // It is definite enough, usually only 4 bytes - ret = false; - WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream IOBuf max"); - } else if (nread == 0) { - return; - } else if (nread < 0 || nread != 4) { // 4 : 4 bytes - ret = false; - WRITE_LOG(LOG_DEBUG, "HdcJdwp::ReadStream program exit pid:%d", ctxJdwp->pid); - } - if (ret) { - pid = atoi(p); - if (pid > 0) { - WRITE_LOG(LOG_DEBUG, "JDWP accept pid:%d", pid); - ctxJdwp->pid = pid; - thisClass->AdminContext(OP_ADD, pid, ctxJdwp); - ret = true; - } - } - Base::ZeroArray(ctxJdwp->buf); - if (!ret) { - thisClass->FreeContext(ctxJdwp); - } -} - -void HdcJdwp::AcceptClient(uv_stream_t *server, int status) -{ - uv_pipe_t *listenPipe = (uv_pipe_t *)server; - HdcJdwp *thisClass = (HdcJdwp *)listenPipe->data; - HCtxJdwp ctxJdwp = (HCtxJdwp)thisClass->MallocContext(); - if (!ctxJdwp) { - return; - } - uv_pipe_init(thisClass->loop, &ctxJdwp->pipe, 1); - if (uv_accept(server, (uv_stream_t *)&ctxJdwp->pipe) < 0) { - WRITE_LOG(LOG_DEBUG, "uv_accept failed"); - thisClass->FreeContext(ctxJdwp); - return; - } - auto funAlloc = [](uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf) -> void { - HCtxJdwp ctxJdwp = (HCtxJdwp)handle->data; - buf->base = (char *)ctxJdwp->buf ; - buf->len = sizeof(ctxJdwp->buf); - }; - uv_read_start((uv_stream_t *)&ctxJdwp->pipe, funAlloc, ReadStream); -} - -// Test bash connnet(UNIX-domain sockets):nc -U path/jdwp-control < hexpid.file -// Test uv connect(pipe): 'uv_pipe_connect' -bool HdcJdwp::JdwpListen() -{ -#ifdef HDC_PCDEBUG - // if test, canbe enable - return true; - const char jdwpCtrlName[] = { 'j', 'd', 'w', 'p', '-', 'c', 'o', 'n', 't', 'r', 'o', 'l', 0 }; - unlink(jdwpCtrlName); -#else - const char jdwpCtrlName[] = { '\0', 'j', 'd', 'w', 'p', '-', 'c', 'o', 'n', 't', 'r', 'o', 'l', 0 }; -#endif - const int DEFAULT_BACKLOG = 4; - bool ret = false; - while (true) { - uv_pipe_init(loop, &listenPipe, 0); - listenPipe.data = this; - if ((uv_pipe_bind(&listenPipe, jdwpCtrlName))) { - WRITE_LOG(LOG_WARN, "Bind error : %d: %s", errno, strerror(errno)); - return 1; - } - if (uv_listen((uv_stream_t *)&listenPipe, DEFAULT_BACKLOG, AcceptClient)) { - break; - } - ++refCount; - ret = true; - break; - } - // listenPipe close by stop - return ret; -} - -// Working in the main thread, but will be accessed by each session thread, so we need to set thread lock -void *HdcJdwp::AdminContext(const uint8_t op, const uint32_t pid, HCtxJdwp ctxJdwp) -{ - HCtxJdwp hRet = nullptr; - switch (op) { - case OP_ADD: { - uv_rwlock_wrlock(&lockMapContext); - mapCtxJdwp[pid] = ctxJdwp; - uv_rwlock_wrunlock(&lockMapContext); - break; - } - case OP_REMOVE: - uv_rwlock_wrlock(&lockMapContext); - mapCtxJdwp.erase(pid); - uv_rwlock_wrunlock(&lockMapContext); - break; - case OP_QUERY: { - uv_rwlock_rdlock(&lockMapContext); - if (mapCtxJdwp.count(pid)) { - hRet = mapCtxJdwp[pid]; - } - uv_rwlock_rdunlock(&lockMapContext); - break; - } - case OP_CLEAR: { - uv_rwlock_wrlock(&lockMapContext); - mapCtxJdwp.clear(); - uv_rwlock_wrunlock(&lockMapContext); - break; - } - default: - break; - } - return hRet; -} - -// work on main thread -void HdcJdwp::SendCallbackJdwpNewFD(uv_write_t *req, int status) -{ - // It usually works successful, not notify session work - HCtxJdwp ctx = (HCtxJdwp)req->data; - if (status >= 0) { - WRITE_LOG(LOG_DEBUG, "SendCallbackJdwpNewFD successful %d, active jdwp forward", ctx->pid); - } else { - WRITE_LOG(LOG_WARN, "SendCallbackJdwpNewFD failed %d", ctx->pid); - } - // close my process's fd - Base::TryCloseHandle((const uv_handle_t *)&ctx->jvmTCP); - delete req; - --ctx->thisClass->refCount; -} - -// Each session calls the interface through the main thread message queue, which cannot be called directly across -// threads -// work on main thread -bool HdcJdwp::SendJdwpNewFD(uint32_t targetPID, int fd) -{ - bool ret = false; - while (true) { - HCtxJdwp ctx = (HCtxJdwp)AdminContext(OP_QUERY, targetPID, nullptr); - if (!ctx) { - break; - } - ctx->dummy = (uint8_t)'!'; - if (uv_tcp_init(loop, &ctx->jvmTCP)) { - break; - } - if (uv_tcp_open(&ctx->jvmTCP, fd)) { - break; - } - // transfer fd to jvm - // clang-format off - if (Base::SendToStreamEx((uv_stream_t *)&ctx->pipe, (uint8_t *)&ctx->dummy, 1, (uv_stream_t *)&ctx->jvmTCP, - (void *)SendCallbackJdwpNewFD, (const void *)ctx) < 0) { - break; - } - // clang-format on - ++refCount; - ret = true; - WRITE_LOG(LOG_DEBUG, "SendJdwpNewFD successful targetPID:%d fd%d", targetPID, fd); - break; - } - return ret; -} - -// cross thread call begin -bool HdcJdwp::CheckPIDExist(uint32_t targetPID) -{ - HCtxJdwp ctx = (HCtxJdwp)AdminContext(OP_QUERY, targetPID, nullptr); - return ctx != nullptr; -} - -string HdcJdwp::GetProcessList() -{ - string ret; - uv_rwlock_rdlock(&lockMapContext); - for (auto &&v : mapCtxJdwp) { - ret += std::to_string(v.first) + "\n"; - } - uv_rwlock_rdunlock(&lockMapContext); - return ret; -} -// cross thread call finish - -// jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8000 -int HdcJdwp::Initial() -{ - if (!JdwpListen()) { - return ERR_MODULE_JDWP_FAILED; - } - return RET_SUCCESS; -} -} \ No newline at end of file diff --git a/services/flashd/daemon/jdwp.h b/services/flashd/daemon/jdwp.h deleted file mode 100755 index 93b3b902..00000000 --- a/services/flashd/daemon/jdwp.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_JDWP_H -#define HDC_JDWP_H -#include "daemon_common.h" - -namespace Hdc { -class HdcJdwp { -public: - HdcJdwp(uv_loop_t *loopIn); - virtual ~HdcJdwp(); - int Initial(); - void Stop(); - bool ReadyForRelease(); - - string GetProcessList(); - bool SendJdwpNewFD(uint32_t targetPID, int fd); - bool CheckPIDExist(uint32_t targetPID); - -private: - struct ContextJdwp { - uint32_t pid; - uv_pipe_t pipe; - HdcJdwp *thisClass; - bool finish; - char buf[sizeof(uint32_t)]; - uint8_t dummy; - uv_tcp_t jvmTCP; - }; - using HCtxJdwp = struct ContextJdwp *; - - bool JdwpListen(); - static void AcceptClient(uv_stream_t *server, int status); - static void ReadStream(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf); - static void SendCallbackJdwpNewFD(uv_write_t *req, int status); - void *MallocContext(); - void FreeContext(HCtxJdwp ctx); - void *AdminContext(const uint8_t op, const uint32_t pid, HCtxJdwp ctxJdwp); - - uv_loop_t *loop; - uv_pipe_t listenPipe; - uint32_t refCount; - map mapCtxJdwp; - uv_rwlock_t lockMapContext; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/daemon/main.cpp b/services/flashd/daemon/main.cpp deleted file mode 100755 index fcd82e87..00000000 --- a/services/flashd/daemon/main.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "daemon_common.h" -using namespace Hdc; - -static bool g_enableUsb = false; -static bool g_enableTcp = false; -static bool g_rootRun = false; -static bool g_backgroundRun = false; -namespace Hdc { -bool RestartDaemon(bool forkchild) -{ - char path[256] = ""; - size_t nPathSize = 256; - uv_exepath(path, &nPathSize); - execl(path, "hdcd", forkchild ? "-forkchild" : nullptr, nullptr); - return true; -} - -bool ForkChildCheck(int argc, const char *argv[]) -{ - // hdcd #service start forground - // hdcd -b #service start backgroundRun - // hdcd -fork #fork - char modeSet[BUF_SIZE_TINY] = ""; - Base::GetHdcProperty("persist.hdc.mode", modeSet, BUF_SIZE_TINY); - Base::PrintMessage("Background mode, persist.hdc.mode"); - string workMode = modeSet; - workMode = Base::Trim(workMode); - if (workMode == CMDSTR_TMODE_TCP) { - WRITE_LOG(LOG_DEBUG, "Property enable TCP"); - g_enableTcp = true; - } else if (workMode == CMDSTR_TMODE_USB) { - WRITE_LOG(LOG_DEBUG, "Property enable USB"); - g_enableUsb = true; - } else if (workMode == "all") { - WRITE_LOG(LOG_DEBUG, "Property enable USB and TCP"); - g_enableUsb = true; - g_enableTcp = true; - } else { - WRITE_LOG(LOG_DEBUG, "Default USB mode"); - g_enableUsb = true; - } - if (argc == CMD_ARG1_COUNT) { - if (!strcmp(argv[1], "-forkchild")) { - g_backgroundRun = false; // forkchild,Forced foreground - } else if (!strcmp(argv[1], "-b")) { - g_backgroundRun = true; - } - } - return true; -} - -int BackgroundRun() -{ - pid_t pc = fork(); // create process as daemon process - if (pc < 0) { - return -1; - } else if (!pc) { - int i; - const int MAX_NUM = 64; - for (i = 0; i < MAX_NUM; ++i) { - close(i); - } - RestartDaemon(true); - } else { // >0 orig process - } - return 0; -} - -string DaemonUsage() -{ - string ret; - ret = "\n Harmony device connector daemon(HDCD) Usage: hdcd [options]...\n\n" - "\n" - "general options:\n" - " -h - Print help\n" - " -l 0-5 - Print runtime log\n" - "\n" - "daemon mode options:\n" - " -b - Daemon run in background/fork mode\n" - " -u - Enable USB mode\n" - " -t - Enable TCP mode\n"; - return ret; -} - -bool GetDaemonCommandlineOptions(int argc, const char *argv[]) -{ - int ch; - // hdcd -l4 ... - WRITE_LOG(LOG_DEBUG, "Fgcli mode"); - // Both settings are running with parameters - while ((ch = getopt(argc, (char *const *)argv, "utl:")) != -1) { - switch (ch) { - case 'l': { - int logLevel = atoi(optarg); - if (logLevel < 0 || logLevel > LOG_LAST) { - WRITE_LOG(LOG_DEBUG, "Loglevel error!\n"); - return -1; - } - Base::SetLogLevel(logLevel); - break; - } - case 'u': { - Base::PrintMessage("Option USB enabled"); - g_enableUsb = true; - break; - } - case 't': { - Base::PrintMessage("Option TCP enabled"); - g_enableTcp = true; - break; - } - default: - Base::PrintMessage("Option:%c non-supported!", ch); - exit(0); - break; - } - } - return true; -} - -void NeedDropPriv() -{ - char droprootSet[BUF_SIZE_TINY] = ""; - Base::GetHdcProperty("persist.hdc.root", droprootSet, BUF_SIZE_TINY); - droprootSet[sizeof(droprootSet) - 1] = '\0'; - string rootMode = droprootSet; - if (Base::Trim(rootMode) == "1") { - setuid(0); - g_rootRun = true; - WRITE_LOG(LOG_DEBUG, "Root run"); - } else if (Base::Trim(rootMode) == "0") { - setuid(AID_SHELL); - } -} -} // namespace Hdc - -#ifndef UNIT_TEST -// daemon running with default behavior. options also can be given to custom its behavior including b/t/u/l etc. -int main(int argc, const char *argv[]) -{ - // check property - if (argc == 2 && !strcmp(argv[1], "-h")) { - string usage = DaemonUsage(); - fprintf(stderr, "%s", usage.c_str()); - return 0; - } - if (argc == CMD_ARG1_COUNT && !strcmp(argv[1], "-v")) { - string ver = Hdc::Base::GetVersion(); - fprintf(stderr, "%s\n", ver.c_str()); - return 0; - } - if (argc == 1 || (argc == CMD_ARG1_COUNT && (!strcmp(argv[1], "-forkchild") || !strcmp(argv[1], "-b")))) { - Base::SetLogLevel(LOG_LEVEL_FULL); - ForkChildCheck(argc, argv); - } else { - GetDaemonCommandlineOptions(argc, argv); - } - if (!g_enableTcp && !g_enableUsb) { - Base::PrintMessage("Both TCP and USB are disable, cannot run continue\n"); - return -1; - } - if (g_backgroundRun) { - return BackgroundRun(); - } - NeedDropPriv(); - umask(0); - signal(SIGPIPE, SIG_IGN); - signal(SIGCHLD, SIG_IGN); - WRITE_LOG(LOG_DEBUG, "HdcDaemon main run"); - HdcDaemon daemon(false); - daemon.InitMod(g_enableTcp, g_enableUsb); - daemon.WorkerPendding(); - bool wantRestart = daemon.WantRestart(); - WRITE_LOG(LOG_DEBUG, "Daemon finish"); - // There is no daemon, we can only restart myself. - if (g_rootRun && wantRestart) { - // just root can self restart, low privilege will be exit and start by service(root) - WRITE_LOG(LOG_INFO, "Daemon restart"); - RestartDaemon(false); - } - return 0; -} -#endif diff --git a/services/flashd/daemon/shell.cpp b/services/flashd/daemon/shell.cpp deleted file mode 100755 index 8a434221..00000000 --- a/services/flashd/daemon/shell.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "shell.h" -#include - -namespace Hdc { -std::mutex HdcShell::mutexPty; - -HdcShell::HdcShell(HTaskInfo hTaskInfo) - : HdcTaskBase(hTaskInfo) -{ - childShell = nullptr; - fdPTY = 0; -} - -HdcShell::~HdcShell() -{ - WRITE_LOG(LOG_DEBUG, "HdcShell deinit"); -}; - -bool HdcShell::ReadyForRelease() -{ - if (!HdcTaskBase::ReadyForRelease()) { - return false; - } - if (!childReady) { - return true; - } - if (!childShell->ReadyForRelease()) { - return false; - } - delete childShell; - childShell = nullptr; - if (fdPTY > 0) { - close(fdPTY); - } - return true; -} - -void HdcShell::StopTask() -{ - singalStop = true; - WRITE_LOG(LOG_DEBUG, "HdcShell::StopTask"); - if (!childReady) { - return; - } - if (childShell) { - childShell->StopWork(false, nullptr); - } - kill(pidShell, SIGKILL); - int status; - waitpid(pidShell, &status, 0); - WRITE_LOG(LOG_DEBUG, "StopTask, kill pidshell:%d", pidShell); -}; - -bool HdcShell::SpecialSignal(uint8_t ch) -{ - const uint8_t TXT_SIGNAL_ETX = 0x3; - bool ret = true; - switch (ch) { - case TXT_SIGNAL_ETX: { // Ctrl+C - pid_t tpgid = tcgetpgrp(fdPTY); - kill(tpgid, SIGINT); - break; - } - default: - ret = false; - break; - } - return ret; -} - -bool HdcShell::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) -{ - switch (command) { - case CMD_SHELL_INIT: { // initial - if (StartShell()) { - LogMsg(MSG_FAIL, "Shell initialize failed"); - } - break; - } - case CMD_SHELL_DATA: - if (!childReady) { - WRITE_LOG(LOG_DEBUG, "Shell not running"); - return false; - } - if (payloadSize == 1 && SpecialSignal(payload[0])) { - } else { - childShell->Write(payload, payloadSize); - } - break; - default: - break; - } - return true; -} - -int HdcShell::ChildForkDo(int pts, const char *cmd, const char *arg0, const char *arg1) -{ - dup2(pts, STDIN_FILENO); - dup2(pts, STDOUT_FILENO); - dup2(pts, STDERR_FILENO); - close(pts); - string text = "/proc/self/oom_score_adj"; - int fd = 0; - if ((fd = open(text.c_str(), O_WRONLY)) >= 0) { - write(fd, "0", 1); - close(fd); - } - char *env = nullptr; - if ((env = getenv("HOME")) && chdir(env) < 0) { - } - execl(cmd, cmd, arg0, arg1, nullptr); - _Exit(1); - return 0; -} - -int HdcShell::ShellFork(const char *cmd, const char *arg0, const char *arg1) -{ - pid_t pid; - pid = fork(); - if (pid < 0) { - WRITE_LOG(LOG_DEBUG, "Fork shell failed:%s", strerror(errno)); - return ERR_GENERIC; - } - if (pid == 0) { - HdcShell::mutexPty.unlock(); - setsid(); - close(ptm); - int pts = 0; - if ((pts = open(devname, O_RDWR | O_CLOEXEC)) < 0) { - return -1; - } - ChildForkDo(pts, cmd, arg0, arg1); - // proc finish - } else { - return pid; - } - return 0; -} - -int HdcShell::CreateSubProcessPTY(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) -{ - ptm = open(devPTMX.c_str(), O_RDWR | O_CLOEXEC); - if (ptm < 0) { - WRITE_LOG(LOG_DEBUG, "Cannot open ptmx, error:%s", strerror(errno)); - return ERR_FILE_OPEN; - } - if (grantpt(ptm) || unlockpt(ptm)) { - WRITE_LOG(LOG_DEBUG, "Cannot open2 ptmx, error:%s", strerror(errno)); - close(ptm); - return ERR_API_FAIL; - } - if (ptsname_r(ptm, devname, sizeof(devname)) != 0) { - WRITE_LOG(LOG_DEBUG, "Trouble with ptmx, error:%s", strerror(errno)); - close(ptm); - return ERR_API_FAIL; - } - *pid = ShellFork(cmd, arg0, arg1); - return ptm; -} - -bool HdcShell::FinishShellProc(const void *context, const bool result, const string exitMsg) -{ - WRITE_LOG(LOG_DEBUG, "FinishShellProc finish"); - HdcShell *thisClass = (HdcShell *)context; - thisClass->TaskFinish(); - --thisClass->refCount; - return true; -}; - -bool HdcShell::ChildReadCallback(const void *context, uint8_t *buf, const int size) -{ - HdcShell *thisClass = (HdcShell *)context; - return thisClass->SendToAnother(CMD_KERNEL_ECHO_RAW, (uint8_t *)buf, size); -}; - -int HdcShell::StartShell() -{ - WRITE_LOG(LOG_DEBUG, "StartShell..."); - int ret = 0; - HdcShell::mutexPty.lock(); - do { - if ((fdPTY = CreateSubProcessPTY(Base::GetShellPath().c_str(), "-", 0, &pidShell)) < 0) { - ret = ERR_PROCESS_SUB_FAIL; - break; - } - childShell = new HdcFileDescriptor(loopTask, fdPTY, this, ChildReadCallback, FinishShellProc); - if (!childShell->StartWork()) { - ret = ERR_API_FAIL; - break; - } - childReady = true; - ++refCount; - } while (false); - if (ret != RET_SUCCESS) { - if (pidShell > 0) { - kill(pidShell, SIGKILL); - } - // fdPTY close by ~clase - } - HdcShell::mutexPty.unlock(); - return ret; -} -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/daemon/shell.h b/services/flashd/daemon/shell.h deleted file mode 100755 index 1c2cda83..00000000 --- a/services/flashd/daemon/shell.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_SHELL_H -#define HDC_SHELL_H -#include "daemon_common.h" -#include - -namespace Hdc { -class HdcShell : public HdcTaskBase { -public: - HdcShell(HTaskInfo hTaskInfo); - virtual ~HdcShell(); - bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); - void StopTask(); - bool ReadyForRelease(); - -private: - static bool FinishShellProc(const void *context, const bool result, const string exitMsg); - static bool ChildReadCallback(const void *context, uint8_t *buf, const int size); - int StartShell(); - int CreateSubProcessPTY(const char *cmd, const char *arg0, const char *arg1, pid_t *pid); - int ChildForkDo(int pts, const char *cmd, const char *arg0, const char *arg1); - bool SpecialSignal(uint8_t ch); - int ShellFork(const char *cmd, const char *arg0, const char *arg1); - - HdcFileDescriptor *childShell; - pid_t pidShell = 0; - int fdPTY; - int ptm = 0; - const string devPTMX = "/dev/ptmx"; - static std::mutex mutexPty; - char devname[BUF_SIZE_SMALL] = ""; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/daemon/usb_ffs.h b/services/flashd/daemon/usb_ffs.h deleted file mode 100755 index 1998daaf..00000000 --- a/services/flashd/daemon/usb_ffs.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_USBFFS_H -#define HDC_USBFFS_H -// clang-format off -#include -#include "daemon_common.h" -// clang-format on - -namespace Hdc { -constexpr auto HDC_USBDR_SND = 0x0; -constexpr auto HDC_USBDR_RCV = 0x80; -constexpr auto HDC_USBMD_BLK = 0X02; -constexpr auto HDC_USBMD_RCV = 0X03; -constexpr auto HDC_CLASS = 0xff; -constexpr auto HDC_SUBCLASS = 0x50; -constexpr auto HDC_FSPKT_SIZE_MAX = 64; -constexpr auto HDC_HSPKT_SIZE_MAX = 512; -constexpr uint16_t HDC_SSPKT_SIZE_MAX = 1024; -constexpr auto USB_FFS_BASE = "/dev/usb-ffs/"; -constexpr auto HDC_USBTF_DEV = 0x01; -constexpr auto HDC_USBTF_CFG = 0x02; -constexpr auto HDC_USBTF_STR = 0x03; -constexpr auto HDC_USBTF_ITF = 0x04; -constexpr auto HDC_USBTF_EPS = 0x05; - -#define SHORT_LE(x) htole16(x) -#define LONG_LE(x) htole32(x) -#define HDC_INTERFACE_NAME "HDC Interface" - -struct UsbFunctionDesc { - struct usb_interface_descriptor ifDesc; - struct usb_endpoint_descriptor_no_audio from; - struct usb_endpoint_descriptor_no_audio to; -} __attribute__((packed)); - -static const struct { - struct usb_functionfs_strings_head head; - struct { - __le16 code; - const char name[sizeof(HDC_INTERFACE_NAME)]; - } __attribute__((packed)) firstItem; -} __attribute__((packed)) USB_FFS_VALUE = { - .head = - { - .magic = LONG_LE(FUNCTIONFS_STRINGS_MAGIC), - .length = LONG_LE(sizeof(USB_FFS_VALUE)), - .str_count = LONG_LE(1), - .lang_count = LONG_LE(1), - }, - .firstItem = - { - SHORT_LE(0x0409), - HDC_INTERFACE_NAME, - }, -}; - -struct UsbFunctionfsDescsHeadOld { - __le32 magic; - __le32 length; - __le32 config1Count; - __le32 config2Count; -} __attribute__((packed)); - -struct UsbFuncConfig { - struct usb_interface_descriptor ifDesc; - struct usb_endpoint_descriptor_no_audio from; - struct usb_ss_ep_comp_descriptor pairFrom; - struct usb_endpoint_descriptor_no_audio to; - struct usb_ss_ep_comp_descriptor pairTo; -} __attribute__((packed)); - -static struct UsbFuncConfig config3 = { - .ifDesc = { - .bLength = sizeof(config3.ifDesc), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = HDC_CLASS, - .bInterfaceSubClass = HDC_SUBCLASS, - .bInterfaceProtocol = VER_PROTOCOL, - .iInterface = 1 - }, - .from = { - .bLength = sizeof(config3.from), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 1 | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = HDC_SSPKT_SIZE_MAX, - }, - .pairFrom = { - .bLength = sizeof(config3.pairFrom), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - .bMaxBurst = 4, - }, - .to = { - .bLength = sizeof(config3.to), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 2 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = HDC_SSPKT_SIZE_MAX, - }, - .pairTo = { - .bLength = sizeof(config3.pairTo), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - .bMaxBurst = 4, - }, -}; - -static struct UsbFunctionDesc config1 = { - .ifDesc = { - .bLength = sizeof(config1.ifDesc), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = HDC_CLASS, - .bInterfaceSubClass = HDC_SUBCLASS, - .bInterfaceProtocol = VER_PROTOCOL, - .iInterface = 1 - }, - .from = { - .bLength = sizeof(config1.from), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 1 | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = HDC_FSPKT_SIZE_MAX, - }, - .to = { - .bLength = sizeof(config1.to), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 2 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = HDC_FSPKT_SIZE_MAX, - }, -}; - -static struct UsbFunctionDesc config2 = { - .ifDesc = { - .bLength = sizeof(config2.ifDesc), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = HDC_CLASS, - .bInterfaceSubClass = HDC_SUBCLASS, - .bInterfaceProtocol = VER_PROTOCOL, - .iInterface = 1 - }, - .from = { - .bLength = sizeof(config2.from), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 1 | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = HDC_HSPKT_SIZE_MAX, - }, - .to = { - .bLength = sizeof(config2.to), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 2 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = HDC_HSPKT_SIZE_MAX, - }, -}; - -static const struct { - struct usb_functionfs_descs_head_v2 head; - __le32 config1Count; - __le32 config2Count; - __le32 config3Count; - __le32 configWosCount; - struct UsbFunctionDesc config1Desc, config2Desc; - struct UsbFuncConfig config3Desc; - struct usb_os_desc_header wosHead; - struct usb_ext_compat_desc wosDesc; -} __attribute__((packed)) USB_FFS_DESC = { - .head = - { - .magic = LONG_LE(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), - .length = LONG_LE(sizeof(USB_FFS_DESC)), - .flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC | - FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC - }, - .config1Count = 3, - .config2Count = 3, - .config3Count = 5, - .configWosCount = 1, - .config1Desc = config1, - .config2Desc = config2, - .config3Desc = config3, - .wosHead = { - .interface = 1, - .dwLength = LONG_LE(sizeof(USB_FFS_DESC.wosHead) + sizeof(USB_FFS_DESC.wosDesc)), - .bcdVersion = SHORT_LE(1), - .wIndex = SHORT_LE(4), - .bCount = 1, - .Reserved = 0, - }, - .wosDesc = { - .bFirstInterfaceNumber = 0, - .Reserved1 = 1, - .CompatibleID = { 'W', 'I', 'N', 'U', 'S', 'B', '\0', '\0'}, - .SubCompatibleID = {0}, - .Reserved2 = {0}, - } -}; -} // namespace Hdc -#endif diff --git a/services/flashd/host/client.cpp b/services/flashd/host/client.cpp index efefabc5..9dc38afe 100755 --- a/services/flashd/host/client.cpp +++ b/services/flashd/host/client.cpp @@ -13,9 +13,12 @@ * limitations under the License. */ #include "client.h" + +#include "host_updater.h" #include "server.h" namespace Hdc { +bool terminalStateChange = false; HdcClient::HdcClient(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn) : HdcChannelBase(serverOrClient, addrString, loopMainIn) { @@ -26,9 +29,8 @@ HdcClient::HdcClient(const bool serverOrClient, const string &addrString, uv_loo HdcClient::~HdcClient() { #ifndef _WIN32 - if (terminalChanged) { + if (terminalStateChange) { tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminalState); - terminalChanged = false; } #endif Base::TryCloseLoop(loopMain, "ExecuteCommand finish"); @@ -217,8 +219,22 @@ void HdcClient::CommandWorker(uv_timer_t *handle) WRITE_LOG(LOG_DEBUG, "Cmd \'%s\' has been canceld", thisClass->command.c_str()); return; } - if (closeInput) { - thisClass->CloseInput(); + while (closeInput) { +#ifndef _WIN32 + if (tcgetattr(STDIN_FILENO, &thisClass->terminalState)) { + break; + } + termios tio; + if (tcgetattr(STDIN_FILENO, &tio)) { + break; + } + cfmakeraw(&tio); + tio.c_cc[VTIME] = 0; + tio.c_cc[VMIN] = 1; + tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio); + terminalStateChange = true; +#endif + break; } thisClass->Send(thisClass->channel->channelId, (uint8_t *)thisClass->command.c_str(), thisClass->command.size() + 1); @@ -253,12 +269,21 @@ void HdcClient::ModifyTty(bool setOrRestore, uv_tty_t *tty) #ifdef _WIN32 uv_tty_set_mode(tty, UV_TTY_MODE_RAW); #else - CloseInput(); + if (tcgetattr(STDIN_FILENO, &terminalState)) { + return; + } + termios tio; + if (tcgetattr(STDIN_FILENO, &tio)) { + return; + } + cfmakeraw(&tio); + tio.c_cc[VTIME] = 0; + tio.c_cc[VMIN] = 1; + tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio); #endif } else { #ifndef _WIN32 tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminalState); - terminalChanged = false; #endif } } @@ -352,20 +377,4 @@ int HdcClient::ReadChannel(HChannel hChannel, uint8_t *buf, const int bytesIO) fflush(stdout); return 0; } - -void HdcClient::CloseInput() -{ -#ifndef _WIN32 - if (tcgetattr(STDIN_FILENO, &terminalState)) - return; - termios tio; - if (tcgetattr(STDIN_FILENO, &tio)) - return; - cfmakeraw(&tio); - tio.c_cc[VTIME] = 0; - tio.c_cc[VMIN] = 1; - tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio); - terminalChanged = true; -#endif -} } // namespace Hdc diff --git a/services/flashd/host/client.h b/services/flashd/host/client.h deleted file mode 100755 index 3efc5700..00000000 --- a/services/flashd/host/client.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_CLIENT_H -#define HDC_CLIENT_H -#include "host_common.h" - -namespace Hdc { -class HdcClient : public HdcChannelBase { -public: - HdcClient(const bool serverOrClient, const string &addrString, uv_loop_t *loopMainIn); - virtual ~HdcClient(); - int Initial(const string &connectKeyIn); - int ExecuteCommand(const string &commandIn); - int CtrlServiceWork(const char *commandIn); - void CloseInput(); -protected: -private: - static void DoCtrlServiceWork(uv_check_t *handle); - static void Connect(uv_connect_t *connection, int status); - static void AllocStdbuf(uv_handle_t *handle, size_t sizeWanted, uv_buf_t *buf); - static void ReadStd(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); - static void CommandWorker(uv_timer_t *handle); - int ConnectServerForClient(const char *ip, uint16_t port); - int ReadChannel(HChannel hChannel, uint8_t *buf, const int bytesIO); - int PreHandshake(HChannel hChannel, const uint8_t *buf); - string AutoConnectKey(string &doCommand, const string &preConnectKey) const; - uint32_t GetLastPID(); - bool StartKillServer(const char *cmd, bool startOrKill); - void BindLocalStd(); - void BindLocalStd(HChannel hChannel); - void ModifyTty(bool setOrRestore, uv_tty_t *tty); - void NotifyInstanceChannelFree(HChannel hChannel); - -#ifndef _WIN32 - termios terminalState; - bool terminalChanged = false; -#endif - string connectKey; - string command; - uint16_t debugRetryCount; - bool bShellInteractive = false; - uv_timer_t waitTimeDoCmd; - uv_check_t ctrlServerWork; - HChannel channel; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/host/host_app.cpp b/services/flashd/host/host_app.cpp deleted file mode 100755 index 938af005..00000000 --- a/services/flashd/host/host_app.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "host_app.h" - -namespace Hdc { -HdcHostApp::HdcHostApp(HTaskInfo hTaskInfo) - : HdcTransferBase(hTaskInfo) -{ - commandBegin = CMD_APP_BEGIN; - commandData = CMD_APP_DATA; -} - -HdcHostApp::~HdcHostApp() -{ -} - -bool HdcHostApp::BeginInstall(CtxFile *context, const char *command) -{ - int argc = 0; - bool ret = false; - string options; - char **argv = Base::SplitCommandToArgs(command, &argc); - if (argc < 1) { - goto Finish; - } - - for (int i = 0; i < argc; ++i) { - if (!strcmp(argv[i], CMD_OPTION_CLIENTCWD.c_str())) { - if (i + 1 < argc) { - context->transferConfig.clientCwd = argv[i + 1]; - i += 1; // add content index - } - } else if (!strncmp(argv[i], "-", 1)) { - if (options.size()) { - options += " "; - } - options += argv[i]; - } else { - string path = argv[i]; - ExtractRelativePath(context->transferConfig.clientCwd, path); - if (MatchPackageExtendName(path, ".hap")) { - context->taskQueue.push_back(path); - } else { - GetSubFiles(argv[i], ".hap", &context->taskQueue); - } - } - } - if (!context->taskQueue.size()) { - LogMsg(MSG_FAIL, "Not any installation package was found"); - return false; - } - // remove repeate - sort(context->taskQueue.begin(), context->taskQueue.end()); - context->taskQueue.erase(unique(context->taskQueue.begin(), context->taskQueue.end()), context->taskQueue.end()); - - context->transferConfig.options = options; - context->transferConfig.functionName = CMDSTR_APP_INSTALL; - RunQueue(context); - ret = true; -Finish: - if (argv) { - delete[]((char *)argv); - } - return ret; -} - -bool HdcHostApp::BeginSideload(CtxFile *context, const char *localPath) -{ - bool ret = false; - context->transferConfig.functionName = CMDSTR_APP_SIDELOAD; - context->taskQueue.push_back(localPath); - RunQueue(context); - ret = true; - return ret; -} - -void HdcHostApp::RunQueue(CtxFile *context) -{ - ++refCount; - context->localPath = context->taskQueue.back(); - uv_fs_open(loopTask, &context->fsOpenReq, context->localPath.c_str(), O_RDONLY, 0, OnFileOpen); - context->master = true; -} - -void HdcHostApp::CheckMaster(CtxFile *context) -{ - uv_fs_t fs; - Base::ZeroStruct(fs.statbuf); - uv_fs_fstat(nullptr, &fs, context->fsOpenReq.result, nullptr); - context->transferConfig.fileSize = fs.statbuf.st_size; - uv_fs_req_cleanup(&fs); - - context->transferConfig.optionalName - = Base::GetRandomString(9); // Prevent the name of illegal APP leads to pm unable to install - if (context->localPath.find(".hap") != (size_t)-1) { - context->transferConfig.optionalName += ".hap"; - } else { - context->transferConfig.optionalName += ".bundle"; - } - string bufString = SerialStruct::SerializeToString(context->transferConfig); - SendToAnother(CMD_APP_CHECK, (uint8_t *)bufString.c_str(), bufString.size()); -} - -bool HdcHostApp::CheckInstallContinue(AppModType mode, bool lastResult, const char *msg) -{ - string modeDesc; - switch (mode) { - case APPMOD_INSTALL: - modeDesc = "App install"; - break; - case APPMOD_UNINSTALL: - modeDesc = "App uninstall"; - break; - case APPMOD_SIDELOAD: - modeDesc = "Side load"; - break; - default: - modeDesc = "Unknow"; - break; - } - ctxNow.taskQueue.pop_back(); - LogMsg(MSG_INFO, "%s path:%s, queuesize:%d, msg:%s", modeDesc.c_str(), ctxNow.localPath.c_str(), - ctxNow.taskQueue.size(), msg); - if (singalStop || !ctxNow.taskQueue.size()) { - LogMsg(MSG_OK, "AppMod finish"); - return false; - } - RunQueue(&ctxNow); - return true; -} - -bool HdcHostApp::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) -{ - if (!HdcTransferBase::CommandDispatch(command, payload, payloadSize)) { - return false; - } - bool ret = true; - constexpr int cmdOffset = 2; - switch (command) { - case CMD_APP_INIT: { - ret = BeginInstall(&ctxNow, (const char *)payload); - break; - } - case CMD_APP_FINISH: { - AppModType mode = (AppModType)payload[0]; - bool result = (bool)payload[1]; - string s(reinterpret_cast(payload + cmdOffset), payloadSize - cmdOffset); - ret = CheckInstallContinue(mode, result, s.c_str()); - break; - } - case CMD_APP_UNINSTALL: { - SendToAnother(CMD_APP_UNINSTALL, payload, payloadSize); - ctxNow.taskQueue.push_back(reinterpret_cast(payload)); // just compatible - break; - } - case CMD_APP_SIDELOAD: { - BeginSideload(&ctxNow, (const char *)payload); - break; - } - default: - break; - } - return ret; -}; -} \ No newline at end of file diff --git a/services/flashd/host/host_app.h b/services/flashd/host/host_app.h deleted file mode 100755 index ad3c8845..00000000 --- a/services/flashd/host/host_app.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_HOST_APP_H -#define HDC_HOST_APP_H -#include "host_common.h" - -namespace Hdc { -class HdcHostApp : public HdcTransferBase { -public: - HdcHostApp(HTaskInfo hTaskInfo); - virtual ~HdcHostApp(); - bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); - -private: - bool BeginInstall(CtxFile *context, const char *command); - void CheckMaster(CtxFile *context); - bool CheckInstallContinue(AppModType mode, bool lastResult, const char *msg); - void RunQueue(CtxFile *context); - bool BeginSideload(CtxFile *context, const char *localPath); -}; -} -#endif \ No newline at end of file diff --git a/services/flashd/host/host_common.h b/services/flashd/host/host_common.h deleted file mode 100755 index e6be2ba5..00000000 --- a/services/flashd/host/host_common.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_HOST_COMMON_H -#define HDC_HOST_COMMON_H - -// clang-format off -#include "../common/common.h" -#include "../common/file.h" -#include "../common/transfer.h" -#include "../common/forward.h" -#include "../common/async_cmd.h" -#include "../common/serial_struct.h" - -#include "host_tcp.h" -#include "host_usb.h" -#include "translate.h" -#include "server_for_client.h" -#include "client.h" -#include "host_app.h" -#include "host_forward.h" -#include "host_unity.h" -#include "host_updater.h" -// clang-format on - -#endif \ No newline at end of file diff --git a/services/flashd/host/host_forward.cpp b/services/flashd/host/host_forward.cpp deleted file mode 100755 index 72cd3f83..00000000 --- a/services/flashd/host/host_forward.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "host_forward.h" - -namespace Hdc { -HdcHostForward::HdcHostForward(HTaskInfo hTaskInfo) - : HdcForwardBase(hTaskInfo) -{ -} - -HdcHostForward::~HdcHostForward() -{ -} -} \ No newline at end of file diff --git a/services/flashd/host/host_forward.h b/services/flashd/host/host_forward.h deleted file mode 100755 index 5c984106..00000000 --- a/services/flashd/host/host_forward.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_HOST_FORWARD_H -#define HDC_HOST_FORWARD_H -#include "host_common.h" - -namespace Hdc { -class HdcHostForward : public HdcForwardBase { -public: - HdcHostForward(HTaskInfo hTaskInfo); - virtual ~HdcHostForward(); - -private: -}; -} // namespace Hdc - -#endif \ No newline at end of file diff --git a/services/flashd/host/host_tcp.cpp b/services/flashd/host/host_tcp.cpp deleted file mode 100755 index 49463605..00000000 --- a/services/flashd/host/host_tcp.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "host_tcp.h" -#include "server.h" - -namespace Hdc { -HdcHostTCP::HdcHostTCP(const bool serverOrDaemonIn, void *ptrMainBase) - : HdcTCPBase(serverOrDaemonIn, ptrMainBase) -{ - broadcastFindWorking = false; -} - -HdcHostTCP::~HdcHostTCP() -{ - WRITE_LOG(LOG_DEBUG, "~HdcHostTCP"); -} - -void HdcHostTCP::Stop() -{ -} - -void HdcHostTCP::RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf) -{ - char bufString[BUF_SIZE_TINY]; - uint16_t port = 0; - char *p = strstr(rcvbuf->base, "-"); - if (!p) { - return; - } - port = atoi(p + 1); - if (!port) { - return; - } - uv_ip4_name((sockaddr_in *)addrSrc, bufString, sizeof(bufString)); - string addrPort = string(bufString); - addrPort += string(":") + std::to_string(port); - lstDaemonResult.push_back(addrPort); -} - -void HdcHostTCP::BroadcastTimer(uv_idle_t *handle) -{ - uv_stop(handle->loop); -} - -// Executive Administration Network Broadcast Discovery, broadcastLanIP==which interface to broadcast -void HdcHostTCP::BroadcatFindDaemon(const char *broadcastLanIP) -{ - if (broadcastFindWorking) { - return; - } - broadcastFindWorking = true; - lstDaemonResult.clear(); - - uv_loop_t loopBroadcast; - uv_loop_init(&loopBroadcast); - struct sockaddr_in addr; - uv_udp_send_t req; - uv_udp_t client; - // send - uv_ip4_addr(broadcastLanIP, 0, &addr); - uv_udp_init(&loopBroadcast, &client); - uv_udp_bind(&client, (const struct sockaddr *)&addr, 0); - uv_udp_set_broadcast(&client, 1); - uv_ip4_addr("255.255.255.255", DEFAULT_PORT, &addr); - uv_buf_t buf = uv_buf_init((char *)HANDSHAKE_MESSAGE.c_str(), HANDSHAKE_MESSAGE.size()); - uv_udp_send(&req, &client, &buf, 1, (const struct sockaddr *)&addr, nullptr); - // recv - uv_udp_t server; - server.data = this; - uv_ip4_addr(broadcastLanIP, DEFAULT_PORT, &addr); - uv_udp_init(&loopBroadcast, &server); - uv_udp_bind(&server, (const struct sockaddr *)&addr, UV_UDP_REUSEADDR); - uv_udp_recv_start(&server, AllocStreamUDP, RecvUDP); - // find timeout - uv_timer_t tLastCheck; - uv_timer_init(&loopBroadcast, &tLastCheck); - uv_timer_start(&tLastCheck, (uv_timer_cb)BroadcastTimer, TIME_BASE, 0); // timeout debug 1s - - uv_run(&loopBroadcast, UV_RUN_DEFAULT); - uv_loop_close(&loopBroadcast); - broadcastFindWorking = false; -} - -void HdcHostTCP::Connect(uv_connect_t *connection, int status) -{ - HSession hSession = (HSession)connection->data; - delete connection; - HdcSessionBase *ptrConnect = (HdcSessionBase *)hSession->classInstance; - auto ctrl = ptrConnect->BuildCtrlString(SP_START_SESSION, 0, nullptr, 0); - if (status < 0) { - goto Finish; - } - if ((hSession->fdChildWorkTCP = Base::DuplicateUvSocket(&hSession->hWorkTCP)) < 0) { - goto Finish; - } - uv_read_stop((uv_stream_t *)&hSession->hWorkTCP); - Base::SetTcpOptions((uv_tcp_t *)&hSession->hWorkTCP); - WRITE_LOG(LOG_DEBUG, "HdcHostTCP::Connect"); - Base::StartWorkThread(&ptrConnect->loopMain, ptrConnect->SessionWorkThread, Base::FinishWorkThread, hSession); - // wait for thread up - while (hSession->childLoop.active_handles == 0) { - uv_sleep(MINOR_TIMEOUT); - } - Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); - return; -Finish: - WRITE_LOG(LOG_FATAL, "Connect failed"); - ptrConnect->FreeSession(hSession->sessionId); -} - -HSession HdcHostTCP::ConnectDaemon(const string &connectKey) -{ - char ip[BUF_SIZE_TINY] = ""; - uint16_t port = 0; - if (Base::ConnectKey2IPPort(connectKey.c_str(), ip, &port) < 0) { - return nullptr; - } - - HdcSessionBase *ptrConnect = (HdcSessionBase *)clsMainBase; - HSession hSession = ptrConnect->MallocSession(true, CONN_TCP, this); - if (!hSession) { - return nullptr; - } - hSession->connectKey = connectKey; - struct sockaddr_in dest; - uv_ip4_addr(ip, port, &dest); - uv_connect_t *conn = new uv_connect_t(); - conn->data = hSession; - uv_tcp_connect(conn, (uv_tcp_t *)&hSession->hWorkTCP, (const struct sockaddr *)&dest, Connect); - return hSession; -} - -void HdcHostTCP::FindLanDaemon() -{ - uv_interface_address_t *info; - int count, i; - char ipAddr[BUF_SIZE_TINY] = ""; - if (broadcastFindWorking) { - return; - } - lstDaemonResult.clear(); - uv_interface_addresses(&info, &count); - i = count; - while (--i) { - uv_interface_address_t interface = info[i]; - if (interface.address.address4.sin_family == AF_INET6) { - continue; - } - uv_ip4_name(&interface.address.address4, ipAddr, sizeof(ipAddr)); - BroadcatFindDaemon(ipAddr); - } - uv_free_interface_addresses(info, count); -} -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/host/host_tcp.h b/services/flashd/host/host_tcp.h deleted file mode 100755 index b5b85ab6..00000000 --- a/services/flashd/host/host_tcp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_HOST_TCP_H -#define HDC_HOST_TCP_H -#include "host_common.h" - -namespace Hdc { -class HdcHostTCP : public HdcTCPBase { -public: - HdcHostTCP(const bool serverOrDaemonIn, void *ptrMainBase); - virtual ~HdcHostTCP(); - void FindLanDaemon(); - HSession ConnectDaemon(const string &connectKey); - void Stop(); - list lstDaemonResult; - -private: - static void BroadcastTimer(uv_idle_t *handle); - static void Connect(uv_connect_t *connection, int status); - void BroadcatFindDaemon(const char *broadcastLanIP); - void RecvUDPEntry(const sockaddr *addrSrc, uv_udp_t *handle, const uv_buf_t *rcvbuf); - - bool broadcastFindWorking; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/host/host_unity.cpp b/services/flashd/host/host_unity.cpp deleted file mode 100755 index 276682eb..00000000 --- a/services/flashd/host/host_unity.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "host_unity.h" - -namespace Hdc { -HdcHostUnity::HdcHostUnity(HTaskInfo hTaskInfo) - : HdcTaskBase(hTaskInfo) -{ - Base::ZeroStruct(opContext); - opContext.thisClass = this; -} - -HdcHostUnity::~HdcHostUnity() -{ - WRITE_LOG(LOG_DEBUG, "HdcHostUnity::~HdcHostUnity finish"); -} - -bool HdcHostUnity::ReadyForRelease() -{ - if (!HdcTaskBase::ReadyForRelease()) { - return false; - } - if (opContext.enableLog && !opContext.hasFilelogClosed) { - return false; - } - return true; -} - -void HdcHostUnity::StopTask() -{ - // Do not detect RunningProtect, force to close - if (opContext.hasFilelogClosed) { - return; - } - if (opContext.enableLog) { - ++refCount; - opContext.fsClose.data = &opContext; - uv_fs_close(loopTask, &opContext.fsClose, opContext.fileLog, OnFileClose); - } -}; - -void HdcHostUnity::OnFileClose(uv_fs_t *req) -{ - uv_fs_req_cleanup(req); - ContextUnity *context = (ContextUnity *)req->data; - HdcHostUnity *thisClass = (HdcHostUnity *)context->thisClass; - context->hasFilelogClosed = true; - --thisClass->refCount; - return; -} - -bool HdcHostUnity::InitLocalLog(const char *path) -{ - uv_fs_t reqFs; - // block open - if (uv_fs_open(nullptr, &reqFs, path, UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, nullptr) - < 0) - return false; - uv_fs_req_cleanup(&reqFs); - opContext.fileLog = reqFs.result; - return true; -} - -void HdcHostUnity::OnFileIO(uv_fs_t *req) -{ - CtxUnityIO *contextIO = (CtxUnityIO *)req->data; - ContextUnity *context = (ContextUnity *)contextIO->context; - HdcHostUnity *thisClass = (HdcHostUnity *)context->thisClass; - uint8_t *bufIO = contextIO->bufIO; - uv_fs_req_cleanup(req); - --thisClass->refCount; - while (true) { - if (req->result <= 0) { - if (req->result < 0) { - WRITE_LOG(LOG_DEBUG, "Error OnFileIO: %s", uv_strerror((int)req->result)); - } - break; - } - context->fileIOIndex += req->result; - break; - } - delete[] bufIO; - delete contextIO; // req is part of contextIO, no need to release -} - -bool HdcHostUnity::AppendLocalLog(const char *bufLog, const int sizeLog) -{ - auto buf = new uint8_t[sizeLog]; - auto contextIO = new CtxUnityIO(); - if (!buf || !contextIO) { - if (buf) { - delete[] buf; - } - if (contextIO) { - delete contextIO; - } - return false; - } - uv_fs_t *req = &contextIO->fs; - contextIO->bufIO = buf; - contextIO->context = &opContext; - req->data = contextIO; - ++refCount; - - if (memcpy_s(buf, sizeLog, bufLog, sizeLog)) { - } - uv_buf_t iov = uv_buf_init((char *)buf, sizeLog); - uv_fs_write(loopTask, req, opContext.fileLog, &iov, 1, opContext.fileBufIndex, OnFileIO); - opContext.fileBufIndex += sizeLog; - return true; -} - -bool HdcHostUnity::CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize) -{ - bool ret = true; - // Both are executed, do not need to detect ChildReady - switch (command) { - case CMD_UNITY_BUGREPORT_INIT: { - if (strlen((char *)payload)) { // enable local log - if (!InitLocalLog((const char *)payload)) { - LogMsg(MSG_FAIL, "Cannot set locallog"); - ret = false; - break; - }; - opContext.enableLog = true; - } - SendToAnother(CMD_UNITY_BUGREPORT_INIT, nullptr, 0); - break; - } - case CMD_UNITY_BUGREPORT_DATA: { - if (opContext.enableLog) { - AppendLocalLog((const char *)payload, payloadSize); - } else { - ServerCommand(CMD_KERNEL_ECHO_RAW, payload, payloadSize); - } - break; - } - default: - break; - } - return ret; -}; -} // namespace Hdc \ No newline at end of file diff --git a/services/flashd/host/host_unity.h b/services/flashd/host/host_unity.h deleted file mode 100755 index e4cb08f8..00000000 --- a/services/flashd/host/host_unity.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_HOST_UNITY_H -#define HDC_HOST_UNITY_H -#include "host_common.h" - -namespace Hdc { -class HdcHostUnity : public HdcTaskBase { -public: - HdcHostUnity(HTaskInfo hTaskInfo); - virtual ~HdcHostUnity(); - bool CommandDispatch(const uint16_t command, uint8_t *payload, const int payloadSize); - void StopTask(); - bool ReadyForRelease(); - -private: - struct ContextUnity { - bool enableLog; - uv_file fileLog; - uint64_t fileIOIndex; - uint64_t fileBufIndex; - bool hasFilelogClosed; - uv_fs_t fsClose; - HdcHostUnity *thisClass; - }; - struct CtxUnityIO { - uv_fs_t fs; - uint8_t *bufIO; - ContextUnity *context; - }; - static void OnFileIO(uv_fs_t *req); - static void OnFileClose(uv_fs_t *req); - bool InitLocalLog(const char *path); - bool AppendLocalLog(const char *bufLog, const int sizeLog); - - ContextUnity opContext; -}; -} // namespace Hdc -#endif // HDC_HOST_UNITY_H \ No newline at end of file diff --git a/services/flashd/host/host_updater.cpp b/services/flashd/host/host_updater.cpp index 1092abc0..641bc1d9 100755 --- a/services/flashd/host/host_updater.cpp +++ b/services/flashd/host/host_updater.cpp @@ -16,6 +16,7 @@ #include #include "common.h" +#include "flash_define.h" #include "transfer.h" #include "serial_struct.h" @@ -164,7 +165,7 @@ bool HostUpdater::CommandDispatch(const uint16_t command, uint8_t *payload, cons bool ret = true; switch (command) { case CMD_UPDATER_BEGIN: { - std::string s(" Processing: 0%%"); + std::string s("Processing: 0%%"); sendProgress = true; SendRawData(reinterpret_cast(s.data()), s.size()); break; @@ -211,7 +212,7 @@ void HostUpdater::ProcessProgress(uint32_t percentage) if (!sendProgress) { return; } - std::string backStr = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; + std::string backStr = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; std::string breakStr = "\n"; WRITE_LOG(LOG_INFO, "ProcessProgress %d", percentage); const int bufferSize = 128; @@ -222,7 +223,7 @@ void HostUpdater::ProcessProgress(uint32_t percentage) sendProgress = false; return; } - int len = sprintf_s(buffer.data(), buffer.size() - 1, "%s Processing: %3d%%", backStr.c_str(), percentage); + int len = sprintf_s(buffer.data(), buffer.size() - 1, "%sProcessing: %3d%%", backStr.c_str(), percentage); HOSTUPDATER_CHECK(len > 0, return, "Failed to format progress info "); SendRawData(reinterpret_cast(buffer.data()), len); if (percentage == PERCENT_FINISH) { @@ -312,7 +313,7 @@ bool HostUpdater::ConfirmCommand(const string &commandIn, bool &closeInput) const size_t minLen = strlen("yes"); int retryCount = 0; do { - printf(" %s ? (Yes/No) ", tip.c_str()); + printf("%s ? (Yes/No) ", tip.c_str()); fflush(stdin); std::string info = {}; size_t i = 0; @@ -347,4 +348,13 @@ bool HostUpdater::ConfirmCommand(const string &commandIn, bool &closeInput) } return true; } + +void HostUpdater::SendRawData(uint8_t *bufPtr, const int size) +{ +#ifndef UPDATER_UT + HdcSessionBase *sessionBase = (HdcSessionBase *)clsSession; + sessionBase->ServerCommand(taskInfo->sessionId, + taskInfo->channelId, CMD_KERNEL_ECHO_RAW, bufPtr, size); +#endif +} } // namespace Hdc \ No newline at end of file diff --git a/services/flashd/host/host_updater.h b/services/flashd/host/host_updater.h index 174dfd4f..f11a5d03 100755 --- a/services/flashd/host/host_updater.h +++ b/services/flashd/host/host_updater.h @@ -47,16 +47,12 @@ private: void RunQueue(CtxFile &context); std::string GetFileName(const std::string &fileName) const; void ProcessProgress(uint32_t percentage); + void SendRawData(uint8_t *bufPtr, const int size); #ifdef UPDATER_UT void LogMsg(MessageLevel level, const char *msg, ...) { return; } - void SendRawData(uint8_t *bufPtr, const int size) - { - std::string s((char *)bufPtr, size); - WRITE_LOG(LOG_DEBUG, "SendRawData %d %s", size, s.c_str()); - } bool SendToAnother(const uint16_t command, uint8_t *bufPtr, const int size) { std::string s((char *)bufPtr, size); diff --git a/services/flashd/host/host_usb.cpp b/services/flashd/host/host_usb.cpp deleted file mode 100755 index 2b9a9f6d..00000000 --- a/services/flashd/host/host_usb.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "host_usb.h" -#include "server.h" - -namespace Hdc { -HdcHostUSB::HdcHostUSB(const bool serverOrDaemonIn, void *ptrMainBase, void *ctxUSBin) - : HdcUSBBase(serverOrDaemonIn, ptrMainBase) -{ - modRunning = false; - if (!ctxUSBin) { - return; - } - HdcServer *pServer = (HdcServer *)ptrMainBase; - uv_idle_init(&pServer->loopMain, &usbWork); - ctxUSB = (libusb_context *)ctxUSBin; - uv_timer_init(&pServer->loopMain, &devListWatcher); -} - -HdcHostUSB::~HdcHostUSB() -{ - if (modRunning) { - Stop(); - } - WRITE_LOG(LOG_DEBUG, "~HdcHostUSB"); -} - -void HdcHostUSB::Stop() -{ - if (!ctxUSB) { - return; - } - Base::TryCloseHandle((uv_handle_t *)&usbWork); - Base::TryCloseHandle((uv_handle_t *)&devListWatcher); - modRunning = false; -} - -int HdcHostUSB::Initial() -{ - if (!ctxUSB) { - WRITE_LOG(LOG_FATAL, "USB mod ctxUSB is nullptr, recompile please"); - return -1; - } - WRITE_LOG(LOG_DEBUG, "HdcHostUSB init"); - modRunning = true; - StartupUSBWork(); // Main thread registration, IO in sub-thread - return 0; -} - -// windows/mac's control port reset seems invalid? So we try to use soft interrupt -// if all platform 'libusb_reset_device()' work ok, commit this function and use it replace -// main thread call -void HdcHostUSB::SendUsbSoftReset(HUSB hUSB, uint32_t sessionId) -{ - struct ResetCtx { - USBHead usbPayloadHeader; - HUSB hUSB; - }; - ResetCtx *ctxReset = new ResetCtx(); - ctxReset->hUSB = hUSB; - - USBHead &usbPayloadHeader = ctxReset->usbPayloadHeader; - usbPayloadHeader.option = USB_OPTION_RESET; - usbPayloadHeader.sessionId = sessionId; - if (memcpy_s(usbPayloadHeader.flag, sizeof(usbPayloadHeader.flag), PACKET_FLAG.c_str(), - sizeof(usbPayloadHeader.flag)) - != EOK) { - delete ctxReset; - return; - } - auto resetUsbCallback = [](struct libusb_transfer *transfer) -> void LIBUSB_CALL { - ResetCtx *ctxReset = (ResetCtx *)transfer->user_data; - if (LIBUSB_TRANSFER_COMPLETED != transfer->status) { - WRITE_LOG(LOG_FATAL, "SendUSBRaw status:%d", transfer->status); - } - ctxReset->hUSB->sendIOComplete = true; - delete ctxReset; - libusb_free_transfer(transfer); - // has send soft reset, next reset daemon's send - WRITE_LOG(LOG_DEBUG, "Device reset singal send"); - }; - hUSB->lockDeviceHandle.lock(); - libusb_transfer *transferUsb = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(transferUsb, hUSB->devHandle, hUSB->epHost, (uint8_t *)&usbPayloadHeader, sizeof(USBHead), - resetUsbCallback, ctxReset, GLOBAL_TIMEOUT * TIME_BASE); - int err = libusb_submit_transfer(transferUsb); - if (err < 0) { - WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", err); - delete ctxReset; - } else { - hUSB->sendIOComplete = false; - } - hUSB->lockDeviceHandle.unlock(); -} - -bool HdcHostUSB::DetectMyNeed(libusb_device *device, string &sn) -{ - bool ret = false; - HUSB hUSB = new HdcUSB(); - hUSB->device = device; - // just get usb SN, close handle immediately - int childRet = OpenDeviceMyNeed(hUSB); - if (childRet < 0) { - delete hUSB; - return false; - } - libusb_release_interface(hUSB->devHandle, hUSB->interfaceNumber); - libusb_close(hUSB->devHandle); - hUSB->devHandle = nullptr; - - WRITE_LOG(LOG_INFO, "Needed device found, busid:%d devid:%d connectkey:%s", hUSB->busId, hUSB->devId, - hUSB->serialNumber.c_str()); - // USB device is automatically connected after recognition, auto connect USB - UpdateUSBDaemonInfo(hUSB, nullptr, STATUS_READY); - HdcServer *hdcServer = (HdcServer *)clsMainBase; - HSession hSession = hdcServer->MallocSession(true, CONN_USB, this); - hSession->connectKey = hUSB->serialNumber; - uv_timer_t *waitTimeDoCmd = new uv_timer_t; - uv_timer_init(&hdcServer->loopMain, waitTimeDoCmd); - waitTimeDoCmd->data = hSession; - constexpr uint16_t PRECONNECT_INTERVAL = 3000; - uv_timer_start(waitTimeDoCmd, hdcServer->UsbPreConnect, 0, PRECONNECT_INTERVAL); - mapIgnoreDevice[sn] = HOST_USB_REGISTER; - ret = true; - delete hUSB; - return ret; -} - -// sub-thread all called -void HdcHostUSB::PenddingUSBIO(uv_idle_t *handle) -{ - libusb_context *ctxUSB = (libusb_context *)handle->data; - // every plug,handle,libusb_handle_events - struct timeval zerotime; - int nComplete = 0; - zerotime.tv_sec = 0; - zerotime.tv_usec = 1; // if == 0,windows will be high CPU load - libusb_handle_events_timeout_completed(ctxUSB, &zerotime, &nComplete); -} - -void HdcHostUSB::KickoutZombie(HSession hSession) -{ - HdcServer *ptrConnect = (HdcServer *)hSession->classInstance; - HUSB hUSB = hSession->hUSB; - if (!hUSB->devHandle || hSession->isDead) { - return; - } - if (LIBUSB_ERROR_NO_DEVICE != libusb_kernel_driver_active(hUSB->devHandle, hUSB->interfaceNumber)) { - return; - } - ptrConnect->FreeSession(hSession->sessionId); -} - -void HdcHostUSB::RemoveIgnoreDevice(string &mountInfo) -{ - if (mapIgnoreDevice.count(mountInfo)) { - mapIgnoreDevice.erase(mountInfo); - } -} - -void HdcHostUSB::ReviewUsbNodeLater(string &nodeKey) -{ - HdcServer *hdcServer = (HdcServer *)clsMainBase; - // add to ignore list - mapIgnoreDevice[nodeKey] = HOST_USB_IGNORE; - int delayRemoveFromList = intervalDevCheck * MINOR_TIMEOUT; // wait little time for daemon reinit - Base::DelayDo(&hdcServer->loopMain, delayRemoveFromList, 0, nodeKey, nullptr, - [this](const uint8_t flag, string &msg, const void *) -> void { RemoveIgnoreDevice(msg); }); -} - -void HdcHostUSB::WatchDevPlugin(uv_timer_t *handle) -{ - HdcHostUSB *thisClass = (HdcHostUSB *)handle->data; - HdcServer *ptrConnect = (HdcServer *)thisClass->clsMainBase; - libusb_device **devs = nullptr; - libusb_device *dev = nullptr; - // kick zombie - ptrConnect->EnumUSBDeviceRegister(KickoutZombie); - // find new - ssize_t cnt = libusb_get_device_list(thisClass->ctxUSB, &devs); - if (cnt < 0) { - WRITE_LOG(LOG_FATAL, "Failed to get device list"); - return; - } - int i = 0; - // linux replug devid increment,windows will be not - while ((dev = devs[i++]) != nullptr) { // must postfix++ - string szTmpKey = Base::StringFormat("%d-%d", libusb_get_bus_number(dev), libusb_get_device_address(dev)); - // check is in ignore list - UsbCheckStatus statusCheck = thisClass->mapIgnoreDevice[szTmpKey]; - if (statusCheck == HOST_USB_IGNORE || statusCheck == HOST_USB_REGISTER) { - continue; - } - string sn = szTmpKey; - if (!thisClass->DetectMyNeed(dev, sn)) { - thisClass->ReviewUsbNodeLater(szTmpKey); - } - } - libusb_free_device_list(devs, 1); -} - -int HdcHostUSB::StartupUSBWork() -{ - // Because libusb(winusb backend) does not support hotplug under win32, we use list mode for all platforms - WRITE_LOG(LOG_DEBUG, "USBHost loopfind mode"); - devListWatcher.data = this; - uv_timer_start(&devListWatcher, WatchDevPlugin, 0, intervalDevCheck); - // Running pendding in independent threads does not significantly improve the efficiency - usbWork.data = ctxUSB; - uv_idle_start(&usbWork, PenddingUSBIO); - return 0; -} - -int HdcHostUSB::CheckDescriptor(HUSB hUSB) -{ - char serialNum[BUF_SIZE_MEDIUM] = ""; - int childRet = 0; - struct libusb_device_descriptor desc; - int curBus = libusb_get_bus_number(hUSB->device); - int curDev = libusb_get_device_address(hUSB->device); - hUSB->busId = curBus; - hUSB->devId = curDev; - if (libusb_get_device_descriptor(hUSB->device, &desc)) { - WRITE_LOG(LOG_DEBUG, "CheckDescriptor libusb_get_device_descriptor failed"); - return -1; - } - // Get the serial number of the device, if there is no serial number, use the ID number to replace - // If the device is not in time, occasionally can't get it, this is determined by the external factor, cannot be - // changed. LIBUSB_SUCCESS - childRet = libusb_get_string_descriptor_ascii(hUSB->devHandle, desc.iSerialNumber, (uint8_t *)serialNum, - sizeof(serialNum)); - if (childRet < 0) { - hUSB->serialNumber = Base::StringFormat("%d-%d", curBus, curDev); - } else { - hUSB->serialNumber = serialNum; - } - return 0; -} - -// hSession can be null -void HdcHostUSB::UpdateUSBDaemonInfo(HUSB hUSB, HSession hSession, uint8_t connStatus) -{ - // add to list - HdcServer *pServer = (HdcServer *)clsMainBase; - HdcDaemonInformation di; - di.connectKey = hUSB->serialNumber; - di.connType = CONN_USB; - di.connStatus = connStatus; - di.hSession = hSession; - di.usbMountPoint = ""; - di.usbMountPoint = Base::StringFormat("%d-%d", hUSB->busId, hUSB->devId); - - HDaemonInfo pDi = nullptr; - HDaemonInfo hdiNew = &di; - pServer->AdminDaemonMap(OP_QUERY, hUSB->serialNumber, pDi); - if (!pDi) { - pServer->AdminDaemonMap(OP_ADD, hUSB->serialNumber, hdiNew); - } else { - pServer->AdminDaemonMap(OP_UPDATE, hUSB->serialNumber, hdiNew); - } -} - -bool HdcHostUSB::IsDebuggableDev(const struct libusb_interface_descriptor *ifDescriptor) -{ - constexpr uint8_t harmonyEpNum = 2; - constexpr uint8_t harmonyClass = 0xff; - constexpr uint8_t harmonySubClass = 0x50; - constexpr uint8_t harmonyProtocol = 0x01; - - if (ifDescriptor->bInterfaceClass != harmonyClass || ifDescriptor->bInterfaceSubClass != harmonySubClass - || ifDescriptor->bInterfaceProtocol != harmonyProtocol) { - return false; - } - if (ifDescriptor->bNumEndpoints != harmonyEpNum) { - return false; - } - return true; -} - -int HdcHostUSB::CheckActiveConfig(libusb_device *device, HUSB hUSB) -{ - unsigned int j = 0; - int ret = -1; - struct libusb_config_descriptor *descConfig = nullptr; - if (libusb_get_active_config_descriptor(device, &descConfig)) { - return -1; - } - for (j = 0; j < descConfig->bNumInterfaces; ++j) { - const struct libusb_interface *interface = &descConfig->interface[j]; - if (interface->num_altsetting >= 1) { - const struct libusb_interface_descriptor *ifDescriptor = &interface->altsetting[0]; - if (!IsDebuggableDev(ifDescriptor)) { - continue; - } - hUSB->interfaceNumber = ifDescriptor->bInterfaceNumber; - unsigned int k = 0; - for (k = 0; k < ifDescriptor->bNumEndpoints; ++k) { - const struct libusb_endpoint_descriptor *ep_desc = &ifDescriptor->endpoint[k]; - if ((ep_desc->bmAttributes & 0x03) == LIBUSB_TRANSFER_TYPE_BULK) { - if (ep_desc->bEndpointAddress & LIBUSB_ENDPOINT_IN) { - hUSB->epDevice = ep_desc->bEndpointAddress; - } else { - hUSB->epHost = ep_desc->bEndpointAddress; - } - hUSB->wMaxPacketSize = ep_desc->wMaxPacketSize; - } - } - if (hUSB->epDevice == 0 || hUSB->epHost == 0) { - break; - } - ret = 0; - } - } - libusb_free_config_descriptor(descConfig); - return ret; -} - -void LIBUSB_CALL HdcHostUSB::ReadUSBBulkCallback(struct libusb_transfer *transfer) -{ - HSession hSession = (HSession)transfer->user_data; - HdcHostUSB *thisClass = (HdcHostUSB *)hSession->classModule; - HUSB hUSB = hSession->hUSB; - bool bOK = false; - int childRet = 0; - constexpr int infinity = 0; // ignore timeout - while (true) { - if (!thisClass->modRunning || (hSession->isDead && 0 == hSession->sendRef)) - break; - if (LIBUSB_TRANSFER_COMPLETED != transfer->status) { - WRITE_LOG(LOG_FATAL, "Host usb not LIBUSB_TRANSFER_COMPLETED, status:%d", transfer->status); - break; - } - childRet - = thisClass->SendToHdcStream(hSession, reinterpret_cast(&hSession->dataPipe[STREAM_MAIN]), - hUSB->bufDevice, transfer->actual_length); - if (childRet != RET_SUCCESS && childRet != ERR_SESSION_NOFOUND) { - break; - } - hUSB->lockDeviceHandle.lock(); - // loop self - libusb_fill_bulk_transfer(transfer, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, hUSB->sizeEpBuf, - ReadUSBBulkCallback, hSession, infinity); - childRet = libusb_submit_transfer(transfer); - hUSB->lockDeviceHandle.unlock(); - if (childRet < 0) { - WRITE_LOG(LOG_FATAL, "libusb_submit_transfer failed, err:%d", childRet); - break; - } - bOK = true; - break; - } - if (!bOK) { - auto server = reinterpret_cast(thisClass->clsMainBase); - server->FreeSession(hSession->sessionId); - hUSB->recvIOComplete = true; - WRITE_LOG(LOG_WARN, "ReadUSBBulkCallback failed"); - } -} - -void HdcHostUSB::RegisterReadCallback(HSession hSession) -{ - HUSB hUSB = hSession->hUSB; - if (hSession->isDead || !modRunning) { - return; - } - hSession->hUSB->transferRecv->user_data = hSession; - hUSB->lockDeviceHandle.lock(); - // first bulk-read must be Okay and no timeout, otherwise failed. - libusb_fill_bulk_transfer(hSession->hUSB->transferRecv, hUSB->devHandle, hUSB->epDevice, hUSB->bufDevice, - hUSB->sizeEpBuf, ReadUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); - int childRet = libusb_submit_transfer(hSession->hUSB->transferRecv); - hUSB->lockDeviceHandle.unlock(); - if (childRet == 0) { - hSession->hUSB->recvIOComplete = false; - } -} - -// ==0 Represents new equipment and is what we need,<0 my need -int HdcHostUSB::OpenDeviceMyNeed(HUSB hUSB) -{ - libusb_device *device = hUSB->device; - int ret = -1; - if (LIBUSB_SUCCESS != libusb_open(device, &hUSB->devHandle)) { - return -100; - } - while (modRunning) { - libusb_device_handle *handle = hUSB->devHandle; - if (CheckDescriptor(hUSB)) { - break; - } - if (CheckActiveConfig(device, hUSB)) { - break; - } - // USB filter rules are set according to specific device - // pedding device - libusb_claim_interface(handle, hUSB->interfaceNumber); - ret = 0; - break; - } - if (ret) { - // not my need device - libusb_close(hUSB->devHandle); - hUSB->devHandle = nullptr; - } - return ret; -} - -// at main thread -void LIBUSB_CALL HdcHostUSB::WriteUSBBulkCallback(struct libusb_transfer *transfer) -{ - USBHead *usbHead = reinterpret_cast(transfer->buffer); - HSession hSession = reinterpret_cast(transfer->user_data); - HdcSessionBase *server = reinterpret_cast(hSession->classInstance); - if (usbHead->option & USB_OPTION_TAIL) { - --hSession->sendRef; - } - if (LIBUSB_TRANSFER_COMPLETED != transfer->status || (hSession->isDead && 0 == hSession->sendRef)) { - WRITE_LOG(LOG_FATAL, "SendUSBRaw status:%d", transfer->status); - if (hSession->hUSB->transferRecv != nullptr) { - libusb_cancel_transfer(hSession->hUSB->transferRecv); - } - server->FreeSession(hSession->sessionId); - } - hSession->hUSB->sendIOComplete = true; - hSession->hUSB->cvTransferSend.notify_one(); -} - -// libusb can send directly across threads?!!! -// Just call from child work thread, it will be block when overlap full -int HdcHostUSB::SendUSBRaw(HSession hSession, uint8_t *data, const int length) -{ - int ret = ERR_GENERIC; - int childRet = -1; - HUSB hUSB = hSession->hUSB; - while (true) { - if (memcpy_s(hUSB->bufHost, length, data, length) != EOK) { - ret = ERR_BUF_COPY; - break; - } - hUSB->lockDeviceHandle.lock(); - std::unique_lock lock(hUSB->lockSend); - hUSB->sendIOComplete = false; - libusb_fill_bulk_transfer(hUSB->transferSend, hUSB->devHandle, hUSB->epHost, hUSB->bufHost, length, - WriteUSBBulkCallback, hSession, GLOBAL_TIMEOUT * TIME_BASE); - childRet = libusb_submit_transfer(hUSB->transferSend); - hUSB->lockDeviceHandle.unlock(); - if (childRet < 0) { - ret = ERR_IO_FAIL; - break; - } - ret = length; - hUSB->cvTransferSend.wait(lock, [hUSB]() { return hUSB->sendIOComplete; }); - break; - } - if (ret < 0) { - --hSession->sendRef; - if (hUSB->transferRecv != nullptr) { - libusb_cancel_transfer(hUSB->transferRecv); - } - } - return ret; -} - -bool HdcHostUSB::FindDeviceByID(HUSB hUSB, const char *usbMountPoint, libusb_context *ctxUSB) -{ - libusb_device **listDevices = nullptr; - bool ret = false; - char tmpStr[BUF_SIZE_TINY] = ""; - int busNum = 0; - int devNum = 0; - int curBus = 0; - int curDev = 0; - - int device_num = libusb_get_device_list(ctxUSB, &listDevices); - if (device_num <= 0) { - libusb_free_device_list(listDevices, 1); - return false; - } - if (strchr(usbMountPoint, '-') && EOK == strcpy_s(tmpStr, sizeof(tmpStr), usbMountPoint)) { - *strchr(tmpStr, '-') = '\0'; - busNum = atoi(tmpStr); - devNum = atoi(tmpStr + strlen(tmpStr) + 1); - } else - return false; - - int i = 0; - for (i = 0; i < device_num; ++i) { - struct libusb_device_descriptor desc; - if (LIBUSB_SUCCESS != libusb_get_device_descriptor(listDevices[i], &desc)) { - break; - } - curBus = libusb_get_bus_number(listDevices[i]); - curDev = libusb_get_device_address(listDevices[i]); - if ((curBus == busNum && curDev == devNum)) { - hUSB->device = listDevices[i]; - int childRet = OpenDeviceMyNeed(hUSB); - if (!childRet) { - ret = true; - } - break; - } - } - libusb_free_device_list(listDevices, 1); - return ret; -} - -bool HdcHostUSB::ReadyForWorkThread(HSession hSession) -{ - HdcUSBBase::ReadyForWorkThread(hSession); - return true; -}; - -// Determines that daemonInfo must have the device -HSession HdcHostUSB::ConnectDetectDaemon(const HSession hSession, const HDaemonInfo pdi) -{ - HdcServer *pServer = (HdcServer *)clsMainBase; - HUSB hUSB = hSession->hUSB; - hUSB->usbMountPoint = pdi->usbMountPoint; - hUSB->ctxUSB = ctxUSB; - if (!FindDeviceByID(hUSB, hUSB->usbMountPoint.c_str(), hUSB->ctxUSB)) { - pServer->FreeSession(hSession->sessionId); - return nullptr; - } - UpdateUSBDaemonInfo(hUSB, hSession, STATUS_CONNECTED); - RegisterReadCallback(hSession); - hUSB->usbMountPoint = pdi->usbMountPoint; - WRITE_LOG(LOG_DEBUG, "HSession HdcHostUSB::ConnectDaemon"); - - Base::StartWorkThread(&pServer->loopMain, pServer->SessionWorkThread, Base::FinishWorkThread, hSession); - // wait for thread up - while (hSession->childLoop.active_handles == 0) { - uv_sleep(1); - } - auto ctrl = pServer->BuildCtrlString(SP_START_SESSION, 0, nullptr, 0); - Base::SendToStream((uv_stream_t *)&hSession->ctrlPipe[STREAM_MAIN], ctrl.data(), ctrl.size()); - return hSession; -} -} // namespace Hdc diff --git a/services/flashd/host/host_usb.h b/services/flashd/host/host_usb.h deleted file mode 100755 index edafd789..00000000 --- a/services/flashd/host/host_usb.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_HOST_USB_H -#define HDC_HOST_USB_H -#include "host_common.h" - -namespace Hdc { -class HdcHostUSB : public HdcUSBBase { -public: - HdcHostUSB(const bool serverOrDaemonIn, void *ptrMainBase, void *ctxUSBin); - virtual ~HdcHostUSB(); - int Initial(); - int SendUSBRaw(HSession hSession, uint8_t *data, const int length); - HSession ConnectDetectDaemon(const HSession hSession, const HDaemonInfo pdi); - void Stop(); - void RemoveIgnoreDevice(string &mountInfo); - -private: - enum UsbCheckStatus { - HOST_USB_IGNORE = 1, - HOST_USB_READY, - HOST_USB_REGISTER, - }; - static int LIBUSB_CALL HotplugHostUSBCallback(libusb_context *ctx, libusb_device *device, - libusb_hotplug_event event, void *userData); - static void PenddingUSBIO(uv_idle_t *handle); - static void WatchDevPlugin(uv_timer_t *handle); - static void KickoutZombie(HSession hSession); - static void LIBUSB_CALL WriteUSBBulkCallback(struct libusb_transfer *transfer); - static void LIBUSB_CALL ReadUSBBulkCallback(struct libusb_transfer *transfer); - int StartupUSBWork(); - int CheckActiveConfig(libusb_device *device, HUSB hUSB); - int OpenDeviceMyNeed(HUSB hUSB); - int CheckDescriptor(HUSB hUSB); - bool IsDebuggableDev(const struct libusb_interface_descriptor *ifDescriptor); - bool ReadyForWorkThread(HSession hSession); - bool FindDeviceByID(HUSB hUSB, const char *usbMountPoint, libusb_context *ctxUSB); - bool DetectMyNeed(libusb_device *device, string &sn); - void SendUsbSoftReset(HUSB hUSB, uint32_t sessionId); - void RestoreHdcProtocol(HUSB hUsb, const uint8_t *buf, int bufSize); - void UpdateUSBDaemonInfo(HUSB hUSB, HSession hSession, uint8_t connStatus); - void RegisterReadCallback(HSession hSession); - void ReviewUsbNodeLater(string &nodeKey); - - uv_idle_t usbWork; - libusb_context *ctxUSB; - uv_timer_t devListWatcher; - map mapIgnoreDevice; - const int intervalDevCheck = 3000; - -private: -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/host/main.cpp b/services/flashd/host/main.cpp index 016e3dc2..ca934bf6 100755 --- a/services/flashd/host/main.cpp +++ b/services/flashd/host/main.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "flash_define.h" #include "server.h" #include "server_for_client.h" diff --git a/services/flashd/host/server.cpp b/services/flashd/host/server.cpp index 90a4b994..6e42d875 100755 --- a/services/flashd/host/server.cpp +++ b/services/flashd/host/server.cpp @@ -14,6 +14,9 @@ */ #include "server.h" +#include "host_updater.h" +#include "flash_define.h" + namespace Hdc { HdcServer::HdcServer(bool serverOrDaemonIn) : HdcSessionBase(serverOrDaemonIn) @@ -141,7 +144,7 @@ bool HdcServer::PullupServer(const char *listenString) // close file pipe close(i); } - execl(path, "hdc", "-m", "-s", listenString, nullptr); + execl(path, "ohflash", "-m", "-s", listenString, nullptr); exit(0); return true; } diff --git a/services/flashd/host/server.h b/services/flashd/host/server.h deleted file mode 100755 index e1e66810..00000000 --- a/services/flashd/host/server.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_SERVER_H -#define HDC_SERVER_H -#include "host_common.h" - -namespace Hdc { -class HdcServer : public HdcSessionBase { -public: - HdcServer(bool serverOrDaemonIn); - virtual ~HdcServer(); - bool FetchCommand(HSession hSession, const uint32_t channelId, const uint16_t command, uint8_t *payload, - const int payloadSize); - string AdminDaemonMap(uint8_t opType, const string &connectKey, HDaemonInfo &hDaemonInfoInOut); - string AdminForwardMap(uint8_t opType, const string &taskString, HForwardInfo &hForwardInfoInOut); - int CreateConnect(const string &connectKey); - bool Initial(const char *listenString); - void AttachChannel(HSession hSession, const uint32_t channelId); - void DeatchChannel(HSession hSession, const uint32_t channelId); - static bool PullupServer(const char *listenString); - static void UsbPreConnect(uv_timer_t *handle); - void NotifyInstanceSessionFree(HSession hSession, bool freeOrClear); - - HdcHostTCP *clsTCPClt; - HdcHostUSB *clsUSBClt; - void *clsServerForClient; - -private: - void ClearInstanceResource(); - void BuildDaemonVisableLine(HDaemonInfo hdi, bool fullDisplay, string &out); - void BuildForwardVisableLine(bool fullOrSimble, HForwardInfo hfi, string &echo); - void ClearMapDaemonInfo(); - bool ServerCommand(const uint32_t sessionId, const uint32_t channelId, const uint16_t command, uint8_t *bufPtr, - const int size); - bool RedirectToTask(HTaskInfo hTaskInfo, HSession hSession, const uint32_t channelId, const uint16_t command, - uint8_t *payload, const int payloadSize); - bool RemoveInstanceTask(const uint8_t op, HTaskInfo hTask); - void BuildForwardVisableLine(HDaemonInfo hdi, char *out, int sizeOutBuf); - bool HandServerAuth(HSession hSession, SessionHandShake &handshake); - string GetDaemonMapList(uint8_t opType); - bool ServerSessionHandshake(HSession hSession, uint8_t *payload, int payloadSize); - void GetDaemonMapOnlyOne(HDaemonInfo &hDaemonInfoInOut); - void TryStopInstance(); - static bool PullupServerWin32(const char *path, const char *listenString); - - uv_rwlock_t daemonAdmin; - map mapDaemon; - uv_rwlock_t forwardAdmin; - map mapForward; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/host/server_for_client.cpp b/services/flashd/host/server_for_client.cpp index fc6feb17..f1db8215 100755 --- a/services/flashd/host/server_for_client.cpp +++ b/services/flashd/host/server_for_client.cpp @@ -13,6 +13,8 @@ * limitations under the License. */ #include "server_for_client.h" + +#include "flash_define.h" #include "server.h" namespace Hdc { diff --git a/services/flashd/host/server_for_client.h b/services/flashd/host/server_for_client.h deleted file mode 100755 index 22ca06e2..00000000 --- a/services/flashd/host/server_for_client.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_SERVERFORCLIENT_H -#define HDC_SERVERFORCLIENT_H -#include "host_common.h" -#include "translate.h" - -namespace Hdc { -class HdcServerForClient : public HdcChannelBase { -public: - HdcServerForClient(const bool serverOrClient, const string &addrString, void *pClsServer, uv_loop_t *loopMainIn); - virtual ~HdcServerForClient(); - int Initial(); - void EchoClient(HChannel hChannel, MessageLevel level, const char *msg, ...); - void EchoClientRaw(const uint32_t channelId, uint8_t *payload, const int payloadSize); - uint16_t GetTCPListenPort(); - void Stop(); - -protected: -private: - static void AcceptClient(uv_stream_t *server, int status); - void SetTCPListen(); - int ReadChannel(HChannel hChannel, uint8_t *bufPtr, const int bytesIO); - bool DoCommand(HChannel hChannel, void *formatCommandInput); - void OrderFindTargets(HChannel hChannel); - bool NewConnectTry(void *ptrServer, HChannel hChannel, const string &connectKey); - static void OrderConnecTargetResult(uv_timer_t *req); - bool SendToDaemon(HChannel hChannel, const uint16_t commandFlag, uint8_t *bufPtr, const int bufSize); - int BindChannelToSession(HChannel hChannel, uint8_t *bufPtr, const int bytesIO); - bool CheckAutoFillTarget(HChannel hChannel); - bool CommandRemoveSession(HChannel hChannel, const char *connectKey); - bool CommandRemoveForward(const string &forwardKey); - bool DoCommandLocal(HChannel hChannel, void *formatCommandInput); - bool DoCommandRemote(HChannel hChannel, void *formatCommandInput); - void GetTargetList(HChannel hChannel, void *formatCommandInput); - bool GetAnyTarget(HChannel hChannel); - bool RemoveForward(HChannel hChannel, const char *parameterString); - bool TaskCommand(HChannel hChannel, void *formatCommandInput); - int ChannelHandShake(HChannel hChannel, uint8_t *bufPtr, const int bytesIO); - bool ChannelSendSessionCtrlMsg(vector &ctrlMsg, uint32_t sessionId); - HSession FindAliveSession(uint32_t sessionId); - HSession FindAliveSessionFromDaemonMap(const HChannel hChannel); - - uv_tcp_t tcpListen; - void *clsServer; -}; -} // namespace Hdc -#endif \ No newline at end of file diff --git a/services/flashd/host/translate.cpp b/services/flashd/host/translate.cpp index 350765eb..e74dbd77 100755 --- a/services/flashd/host/translate.cpp +++ b/services/flashd/host/translate.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ #include "translate.h" +#include "host_updater.h" namespace Hdc { namespace TranslateCommand { diff --git a/services/flashd/host/translate.h b/services/flashd/host/translate.h deleted file mode 100755 index 96128e50..00000000 --- a/services/flashd/host/translate.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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. - */ -#ifndef HDC_TRANSLATE_H -#define HDC_TRANSLATE_H -#include "host_common.h" - -namespace Hdc { -namespace TranslateCommand { - struct FormatCommand { - uint16_t cmdFlag; - string parameters; - bool bJumpDo; - }; - - string String2FormatCommand(const char *inputRaw, int sizeInputRaw, FormatCommand *outCmd); - string Usage(); -} -} -#endif \ No newline at end of file diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 8fd94283..5ad65418 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -176,6 +176,9 @@ ohos_unittest("updater_unittest") { "//base/update/updater/services/diffpatch/bzip2", "//base/update/updater/services/ui", "//base/update/updater/test/unittest", + "//developtools/hdc_standard/src/common", + "//developtools/hdc_standard/src/host", + "//developtools/hdc_standard/src/daemon", "//third_party/zlib", "//third_party/lz4/lib", "//third_party/bounds_checking_function/include", diff --git a/test/unittest/flashd_test/flash_host_unittest.cpp b/test/unittest/flashd_test/flash_host_unittest.cpp index 36561822..00c2bf3a 100755 --- a/test/unittest/flashd_test/flash_host_unittest.cpp +++ b/test/unittest/flashd_test/flash_host_unittest.cpp @@ -18,10 +18,11 @@ #include #include -#include "common/common.h" -#include "common/transfer.h" +#include "common.h" +#include "flash_define.h" #include "host_updater.h" #include "serial_struct.h" +#include "transfer.h" #include "unittest_comm.h" using namespace std; @@ -197,11 +198,6 @@ HWTEST_F(FLashHostUnitTest, TestFlashHostMatch, TestSize.Level1) EXPECT_EQ(cmdFlag, CMD_UPDATER_FORMAT); EXPECT_EQ(bJumpDo == false, 1); - ret = HostUpdater::CheckMatchUpdate("flash", stringError, cmdFlag, bJumpDo); - EXPECT_EQ(ret == true, 1); - EXPECT_EQ(cmdFlag, CMD_KERNEL_HELP); - EXPECT_EQ(bJumpDo == true, 1); - bJumpDo = false; ret = HostUpdater::CheckMatchUpdate("install aaa.hap", stringError, cmdFlag, bJumpDo); EXPECT_EQ(ret == false, 1); diff --git a/test/unittest/flashd_test/flash_service_unittest.cpp b/test/unittest/flashd_test/flash_service_unittest.cpp index 3272f947..32b63600 100755 --- a/test/unittest/flashd_test/flash_service_unittest.cpp +++ b/test/unittest/flashd_test/flash_service_unittest.cpp @@ -18,13 +18,14 @@ #include #include -#include "common/common.h" -#include "common/transfer.h" +#include "common.h" #include "daemon_updater.h" +#include "flash_define.h" #include "flash_service.h" #include "flashd/flashd.h" #include "fs_manager/mount.h" #include "serial_struct.h" +#include "transfer.h" #include "unittest_comm.h" using namespace std; -- Gitee From 1dbacfa0fb3c618e991877c434f7e60a25f7a165 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Wed, 17 Nov 2021 11:52:13 +0800 Subject: [PATCH 56/94] updater: fix codedex Signed-off-by: xionglei6 --- services/diffpatch/diff/blocks_diff.cpp | 4 +-- services/flashd/BUILD.gn | 2 +- services/flashd/host/client.cpp | 2 +- services/flashd/host/host_updater.cpp | 12 ++------- services/flashd/host/main.cpp | 21 ++++----------- services/flashd/host/server.cpp | 4 +-- services/flashd/host/server_for_client.cpp | 19 +++++++------- services/flashd/host/translate.cpp | 26 ++++++++++--------- .../flashd_test/flash_host_unittest.cpp | 4 --- 9 files changed, 36 insertions(+), 58 deletions(-) diff --git a/services/diffpatch/diff/blocks_diff.cpp b/services/diffpatch/diff/blocks_diff.cpp index d579dbd9..2a68f28c 100644 --- a/services/diffpatch/diff/blocks_diff.cpp +++ b/services/diffpatch/diff/blocks_diff.cpp @@ -237,7 +237,7 @@ void BlocksDiff::ComputeLength(const BlockBuffer &newInfo, int64_t i = 0; int64_t s = 0; int64_t tmp = 0; - for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length)); ) { + for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length));) { if (oldInfo.buffer[lastPos_ + i] == newInfo.buffer[lastScan_ + i]) { s++; } @@ -413,7 +413,7 @@ void SuffixArray::Init(const BlockBuffer &oldInfo) DataType len = 0; for (h = 1; suffixArray_[0] != -(static_cast(oldInfo.length) + 1); h += h) { len = 0; - for (i = 0; i < (static_cast(oldInfo.length) + 1); ) { + for (i = 0; i < (static_cast(oldInfo.length) + 1);) { if (suffixArray_[i] < 0) { len -= suffixArray_[i]; i -= suffixArray_[i]; diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn index 7a30a9fb..a0f49ad4 100755 --- a/services/flashd/BUILD.gn +++ b/services/flashd/BUILD.gn @@ -17,7 +17,7 @@ FLASHD_PATH = "//base/update/updater/services/flashd" HDC_PATH = "//developtools/hdc_standard/src" common_sources = [ - "${FLASHD_PATH}/common/base.cpp", + "${HDC_PATH}/common/base.cpp", "${HDC_PATH}/common/async_cmd.cpp", "${HDC_PATH}/common/auth.cpp", "${HDC_PATH}/common/channel.cpp", diff --git a/services/flashd/host/client.cpp b/services/flashd/host/client.cpp index 9dc38afe..a1b93bcd 100755 --- a/services/flashd/host/client.cpp +++ b/services/flashd/host/client.cpp @@ -373,7 +373,7 @@ int HdcClient::ReadChannel(HChannel hChannel, uint8_t *buf, const int bytesIO) #endif WRITE_LOG(LOG_DEBUG, "Client ReadChannel :%d", bytesIO); string s(reinterpret_cast(buf), bytesIO); - fprintf(stdout, "%s", s.c_str()); + (void)fprintf(stdout, "%s", s.c_str()); fflush(stdout); return 0; } diff --git a/services/flashd/host/host_updater.cpp b/services/flashd/host/host_updater.cpp index 641bc1d9..9cd19ffb 100755 --- a/services/flashd/host/host_updater.cpp +++ b/services/flashd/host/host_updater.cpp @@ -292,7 +292,6 @@ void HostUpdater::SetInput(const std::string &input) bool HostUpdater::ConfirmCommand(const string &commandIn, bool &closeInput) { std::string tip = ""; - WRITE_LOG(LOG_DEBUG, "ConfirmCommand \"%s\" \n", commandIn.c_str()); if (!strncmp(commandIn.c_str(), updateCmd.c_str(), updateCmd.size())) { closeInput = true; } else if (!strncmp(commandIn.c_str(), flashCmd.c_str(), flashCmd.size())) { @@ -303,11 +302,7 @@ bool HostUpdater::ConfirmCommand(const string &commandIn, bool &closeInput) } else if (!strncmp(commandIn.c_str(), formatCmd.c_str(), formatCmd.size())) { tip = "Confirm format partition"; } - if (tip.empty()) { - return true; - } - // check if -f - if (strstr(commandIn.c_str(), " -f") != nullptr) { + if (tip.empty() || strstr(commandIn.c_str(), " -f") != nullptr) { // check if -f return true; } const size_t minLen = strlen("yes"); @@ -343,10 +338,7 @@ bool HostUpdater::ConfirmCommand(const string &commandIn, bool &closeInput) } retryCount++; } while (retryCount < 3); // 3 retry max count - if (retryCount >= 3) { // 3 retry max count - return false; - } - return true; + return (retryCount >= 3) ? false : true; // 3 retry max count } void HostUpdater::SendRawData(uint8_t *bufPtr, const int size) diff --git a/services/flashd/host/main.cpp b/services/flashd/host/main.cpp index ca934bf6..878428c7 100755 --- a/services/flashd/host/main.cpp +++ b/services/flashd/host/main.cpp @@ -16,13 +16,6 @@ #include "server.h" #include "server_for_client.h" -#ifndef HARMONY_PROJECT -#include "../test/ut_command.h" -using namespace HdcTest; -#endif - -#include "server.h" -#include "server_for_client.h" using namespace Hdc; static bool g_isServerMode = false; @@ -60,7 +53,7 @@ int IsRegisterCommand(string &outCommand, const char *cmd, const char *cmdnext) for (string v : registerCommand) { if (doubleCommand == v) { outCommand = doubleCommand; - return 2; + return 2; // 2 error code } if (cmd == v) { outCommand = cmd; @@ -97,7 +90,7 @@ int SplitOptionAndCommand(int argc, const char **argv, string &outOption, string resultChild = IsRegisterCommand(outCommand, argv[i], (i == argc - 1) ? nullptr : argv[i + 1]); if (resultChild > 0) { foundCommand = true; - if (resultChild == 2) { + if (resultChild == 2) { // 2 error code ++i; } AppendCwdWhenTransfer(outCommand); @@ -130,9 +123,6 @@ int RunServerMode(string &serverListenString) int RunPcDebugMode(bool isPullServer, bool isTCPorUSB, int isTestMethod) { -#ifdef HARMONY_PROJECT - Base::PrintMessage("Not support command..."); -#else pthread_t pt; if (isPullServer) { pthread_create(&pt, nullptr, TestBackgroundServerForClient, nullptr); @@ -143,7 +133,6 @@ int RunPcDebugMode(bool isPullServer, bool isTCPorUSB, int isTestMethod) pthread_join(pt, nullptr); WRITE_LOG(LOG_DEBUG, "!!!!!!!!!Server finish"); } -#endif return 0; } @@ -167,7 +156,7 @@ int RunClientMode(string &commands, string &serverListenString, string &connectK && Base::ProgramMutex(SERVER_NAME.c_str(), true) == 0) { // default pullup, just default listenstr.If want to customer listen-string, please use 'hdc -m -s lanip:port' HdcServer::PullupServer(DEFAULT_SERVER_ADDR.c_str()); - uv_sleep(300); // give time to start serverForClient,at least 200ms + uv_sleep(300); // give time to start serverForClient,at least 300ms } client.Initial(connectKey); client.ExecuteCommand(commands.c_str()); @@ -176,7 +165,7 @@ int RunClientMode(string &commands, string &serverListenString, string &connectK bool ParseServerListenString(string &serverListenString, char *optarg) { - if (strlen(optarg) > 24) { + if (strlen(optarg) > 24) { // 24 min len Base::PrintMessage("Unknow content of parament '-s'"); return false; } @@ -186,7 +175,7 @@ bool ParseServerListenString(string &serverListenString, char *optarg) } char *p = strchr(buf, ':'); if (!p) { // Only port - if (strlen(buf) > 5) { + if (strlen(buf) > 5) { // port len Base::PrintMessage("The port-string's length must < 5"); return false; } diff --git a/services/flashd/host/server.cpp b/services/flashd/host/server.cpp index 6e42d875..1d8097bc 100755 --- a/services/flashd/host/server.cpp +++ b/services/flashd/host/server.cpp @@ -490,7 +490,7 @@ bool HdcServer::FetchCommand(HSession hSession, const uint32_t channelId, const pdiNew->channelId = channelId; pdiNew->sessionId = hSession->sessionId; pdiNew->forwardDirection = ((char *)payload)[0] == '1'; - pdiNew->taskString = (char *)payload + 2; + pdiNew->taskString = (char *)payload + 2; // 2 len AdminForwardMap(OP_ADD, STRING_EMPTY, pdiNew); Base::TryCloseHandle((uv_handle_t *)&hChannel->hChildWorkTCP); // detch client channel break; @@ -637,7 +637,7 @@ int HdcServer::CreateConnect(const string &connectKey) uv_timer_t *waitTimeDoCmd = new uv_timer_t; uv_timer_init(&loopMain, waitTimeDoCmd); waitTimeDoCmd->data = hSession; - uv_timer_start(waitTimeDoCmd, UsbPreConnect, 10, 100); + uv_timer_start(waitTimeDoCmd, UsbPreConnect, 10, 100); // 10 100 repeat } if (!hSession) { return ERR_BUF_ALLOC; diff --git a/services/flashd/host/server_for_client.cpp b/services/flashd/host/server_for_client.cpp index f1db8215..496b0bbf 100755 --- a/services/flashd/host/server_for_client.cpp +++ b/services/flashd/host/server_for_client.cpp @@ -81,7 +81,7 @@ void HdcServerForClient::SetTCPListen() uv_tcp_init(loopMain, &tcpListen); uv_ip4_addr(channelHost.c_str(), channelPort, &addr); uv_tcp_bind(&tcpListen, (const struct sockaddr *)&addr, 0); - uv_listen((uv_stream_t *)&tcpListen, 128, (uv_connection_cb)AcceptClient); + uv_listen((uv_stream_t *)&tcpListen, 128, (uv_connection_cb)AcceptClient); // 128 client } int HdcServerForClient::Initial() @@ -92,7 +92,7 @@ int HdcServerForClient::Initial() } if (!channelHostPort.size() || !channelHost.size() || !channelPort) { WRITE_LOG(LOG_FATAL, "Listen string initial failed"); - return -2; + return -2; // 2 error code } SetTCPListen(); return 0; @@ -206,8 +206,7 @@ void HdcServerForClient::OrderConnecTargetResult(uv_timer_t *req) } else { uint16_t *bRetryCount = (uint16_t *)hChannel->bufStd; ++(*bRetryCount); - if (*bRetryCount > 500) { - // 5s + if (*bRetryCount > 500) { // 500 ms bExitRepet = true; sRet = "Connect failed"; thisClass->EchoClient(hChannel, MSG_FAIL, (char *)sRet.c_str()); @@ -228,15 +227,15 @@ bool HdcServerForClient::NewConnectTry(void *ptrServer, HChannel hChannel, const bool ret = false; if (-1 == childRet) { EchoClient(hChannel, MSG_INFO, "Target is connected, repeat operation"); - } else if (-2 == childRet) { + } else if (-2 == childRet) { // 2 error code EchoClient(hChannel, MSG_FAIL, "CreateConnect failed"); WRITE_LOG(LOG_FATAL, "CreateConnect failed"); } else { - Base::ZeroBuf(hChannel->bufStd, 2); - childRet = snprintf_s(hChannel->bufStd + 2, sizeof(hChannel->bufStd) - 2, sizeof(hChannel->bufStd) - 3, "%s", - (char *)connectKey.c_str()); + Base::ZeroBuf(hChannel->bufStd, 2); // 2 len + childRet = snprintf_s(hChannel->bufStd + 2, sizeof(hChannel->bufStd) - 2, // 2 len + sizeof(hChannel->bufStd) - 3, "%s", (char *)connectKey.c_str()); // 3 len if (childRet > 0) { - Base::TimerUvTask(loopMain, hChannel, OrderConnecTargetResult, 10); + Base::TimerUvTask(loopMain, hChannel, OrderConnecTargetResult, 10); // 10 repeat ret = true; } } @@ -639,7 +638,7 @@ int HdcServerForClient::ReadChannel(HChannel hChannel, uint8_t *bufPtr, const in } } if (formatCommand.bJumpDo) { - ret = -10; + ret = -10; // 10 error code return ret; } } else { diff --git a/services/flashd/host/translate.cpp b/services/flashd/host/translate.cpp index e74dbd77..5b274307 100755 --- a/services/flashd/host/translate.cpp +++ b/services/flashd/host/translate.cpp @@ -57,7 +57,7 @@ namespace TranslateCommand { { string stringError; if (Base::StringEndsWith(outCmd->parameters, " -remove")) { - outCmd->parameters = outCmd->parameters.substr(0, outCmd->parameters.size() - 8); + outCmd->parameters = outCmd->parameters.substr(0, outCmd->parameters.size() - 8); // 8 leng outCmd->cmdFlag = CMD_KERNEL_TARGET_DISCONNECT; } else { outCmd->cmdFlag = CMD_KERNEL_TARGET_CONNECT; @@ -92,10 +92,14 @@ namespace TranslateCommand { outCmd->parameters = input + 9; // 9 rm extra size } } else { - const char *p = input + 6; + const char *p = input + 6; // 6 length // clang-format off - if (strncmp(p, "tcp:", 4) && strncmp(p, "localabstract:", 14) && strncmp(p, "localreserved:", 14) && - strncmp(p, "localfilesystem:", 16) && strncmp(p, "dev:", 4) && strncmp(p, "jdwp:", 5)) { + if (strncmp(p, "tcp:", 4) && // 4 legnth of tcp + strncmp(p, "localabstract:", 14) && // 14 legnth of localabstract + strncmp(p, "localreserved:", 14) && // 14 legnth of localreserved + strncmp(p, "localfilesystem:", 16) && // 14 legnth of localfilesystem + strncmp(p, "dev:", 4) && // 4 legnth of dev + strncmp(p, "jdwp:", 5)) { // 14 legnth of jdwp stringError = "Incorrect forward command"; outCmd->bJumpDo = true; } @@ -111,12 +115,12 @@ namespace TranslateCommand { string stringError; outCmd->cmdFlag = CMD_UNITY_RUNMODE; outCmd->parameters = input + CMDSTR_TARGET_MODE.size() + 1; // with ' ' - if (!strncmp(outCmd->parameters.c_str(), "port", 4) + if (!strncmp(outCmd->parameters.c_str(), "port", 4) // 4 port len && !strcmp(outCmd->parameters.c_str(), CMDSTR_TMODE_USB.c_str())) { stringError = "Error tmode command"; outCmd->bJumpDo = true; - } else if (!strncmp(outCmd->parameters.c_str(), "port ", 5)) { - int port = atoi(input + 4); + } else if (!strncmp(outCmd->parameters.c_str(), "port ", 5)) { // 5 port len + int port = atoi(input + 4); // 4 port len if (port > MAX_IP_PORT || port <= 0) { stringError = "Incorrect port range"; outCmd->bJumpDo = true; @@ -130,7 +134,7 @@ namespace TranslateCommand { string stringError; outCmd->cmdFlag = CMD_UNITY_REBOOT; if (strcmp(input, CMDSTR_TARGET_REBOOT.c_str())) { - outCmd->parameters = input + 12; + outCmd->parameters = input + 12; // 12 length of target boot if (outCmd->parameters != "-bootloader" && outCmd->parameters != "-recovery" && outCmd->parameters != "-flashd") { stringError = "Error reboot paramenter"; @@ -192,7 +196,7 @@ namespace TranslateCommand { } else if (!strncmp(input.c_str(), CMDSTR_APP_UNINSTALL.c_str(), CMDSTR_APP_UNINSTALL.size())) { outCmd->cmdFlag = CMD_APP_UNINSTALL; outCmd->parameters = input; - if (outCmd->parameters.size() > 512 || outCmd->parameters.size() < 4) { + if (outCmd->parameters.size() > 512 || outCmd->parameters.size() < 4) { // 512 4 max and min name length stringError = "Package's path incorrect"; outCmd->bJumpDo = true; } @@ -229,9 +233,7 @@ namespace TranslateCommand { if (outCmd->parameters.size() == CMDSTR_BUGREPORT.size()) { outCmd->parameters += " "; } - } - // Inner command, protocol uses only - else if (input == CMDSTR_INNER_ENABLE_KEEPALIVE) { + } else if (input == CMDSTR_INNER_ENABLE_KEEPALIVE) { // Inner command, protocol uses only outCmd->cmdFlag = CMD_KERNEL_ENABLE_KEEPALIVE; } else if (HostUpdater::CheckMatchUpdate(input, stringError, outCmd->cmdFlag, outCmd->bJumpDo)) { outCmd->parameters = input; diff --git a/test/unittest/flashd_test/flash_host_unittest.cpp b/test/unittest/flashd_test/flash_host_unittest.cpp index 00c2bf3a..d7c4e068 100755 --- a/test/unittest/flashd_test/flash_host_unittest.cpp +++ b/test/unittest/flashd_test/flash_host_unittest.cpp @@ -64,13 +64,11 @@ public: } flashHost->CommandDispatch(command, const_cast(reinterpret_cast(cmd.data())), cmd.size()); - return 0; } int TestFlashProgress(uint16_t command, const std::string &cmd, uint32_t progress) { - HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); if (task == nullptr) { @@ -114,7 +112,6 @@ public: (void)memcpy_s(cmdInfo.data(), cmdInfo.size(), &percentage, sizeof(percentage)); flashHost->CommandDispatch(CMD_UPDATER_PROGRESS, const_cast(reinterpret_cast(cmdInfo.data())), cmdInfo.size()); - return 0; } }; @@ -139,7 +136,6 @@ HWTEST_F(FLashHostUnitTest, TestFlashHostFormat, TestSize.Level1) cmdParam += " -t ext4"; EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FORMAT, cmdParam)); - cmdParam = "format "; cmdParam += TEST_PARTITION_NAME; cmdParam += " -t ext4"; -- Gitee From cbb191f11102dc77716c47a74d05a86c6813e03a Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Wed, 17 Nov 2021 14:13:49 +0800 Subject: [PATCH 57/94] updater: fix bugs Signed-off-by: xionglei6 --- services/flashd/BUILD.gn | 2 +- services/flashd/common/base.cpp | 1249 ----------------------- services/flashd/daemon/daemon_unity.cpp | 2 - services/flashd/host/client.cpp | 2 +- services/flashd/host/main.cpp | 2 +- 5 files changed, 3 insertions(+), 1254 deletions(-) delete mode 100755 services/flashd/common/base.cpp diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn index a0f49ad4..ab998573 100755 --- a/services/flashd/BUILD.gn +++ b/services/flashd/BUILD.gn @@ -17,9 +17,9 @@ FLASHD_PATH = "//base/update/updater/services/flashd" HDC_PATH = "//developtools/hdc_standard/src" common_sources = [ - "${HDC_PATH}/common/base.cpp", "${HDC_PATH}/common/async_cmd.cpp", "${HDC_PATH}/common/auth.cpp", + "${HDC_PATH}/common/base.cpp", "${HDC_PATH}/common/channel.cpp", "${HDC_PATH}/common/debug.cpp", "${HDC_PATH}/common/file.cpp", diff --git a/services/flashd/common/base.cpp b/services/flashd/common/base.cpp deleted file mode 100755 index b0e7f153..00000000 --- a/services/flashd/common/base.cpp +++ /dev/null @@ -1,1249 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * 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 "base.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __MUSL__ -extern "C" { -#include "parameter.h" -} -#endif -using namespace std::chrono; - -namespace Hdc { -namespace Base { - uint8_t g_logLevel = 0; - void SetLogLevel(const uint8_t logLevel) - { - g_logLevel = logLevel; - } - -// Commenting the code will optimize and tune all log codes, and the compilation volume will be greatly reduced -#define ENABLE_DEBUGLOG -#ifdef ENABLE_DEBUGLOG - void GetLogDebugFunctioname(string &debugInfo, int line, string &threadIdString) - { - string tmpString = GetFileNameAny(debugInfo); - debugInfo = StringFormat("%s:%d", tmpString.c_str(), line); - if (g_logLevel < LOG_FULL) { - debugInfo = ""; - threadIdString = ""; - } else { - debugInfo = "[" + debugInfo + "]"; - threadIdString = StringFormat("[%x]", std::hash {}(std::this_thread::get_id())); - } - } - - bool IsWindowsSupportAnsiColor() - { -#ifdef _WIN32 - // Set output mode to handle virtual terminal sequences - HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); - if (hOut == INVALID_HANDLE_VALUE) { - return false; - } - DWORD dwMode = 0; - if (!GetConsoleMode(hOut, &dwMode)) { - return false; - } - dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - if (!SetConsoleMode(hOut, dwMode)) { - return false; - } -#endif - return true; - } - - void GetLogLevelAndTime(uint8_t logLevel, string &logLevelString, string &timeString) - { - system_clock::time_point timeNow = system_clock::now(); // now time - system_clock::duration sinceUnix0 = timeNow.time_since_epoch(); // since 1970 - time_t sSinceUnix0 = duration_cast(sinceUnix0).count(); - std::tm tim = *std::localtime(&sSinceUnix0); - bool enableAnsiColor = false; -#ifdef _WIN32 - enableAnsiColor = IsWindowsSupportAnsiColor(); -#else - enableAnsiColor = true; -#endif - if (enableAnsiColor) { - switch (logLevel) { - case LOG_FATAL: - logLevelString = "\033[1;31mF\033[0m"; - break; - case LOG_INFO: - logLevelString = "\033[1;32mI\033[0m"; - break; - case LOG_WARN: - logLevelString = "\033[1;33mW\033[0m"; - break; - case LOG_DEBUG: - logLevelString = "\033[1;36mD\033[0m"; - break; - default: - logLevelString = "\033[1;36mD\033[0m"; - break; - } - } else { - logLevelString = std::to_string(logLevel); - } - string msTimeSurplus; - if (g_logLevel > LOG_DEBUG) { - const auto sSinceUnix0Rest = duration_cast(sinceUnix0).count() % (TIME_BASE * TIME_BASE); - msTimeSurplus = StringFormat(".%06llu", sSinceUnix0Rest); - } - timeString = StringFormat("%d:%d:%d%s", tim.tm_hour, tim.tm_min, tim.tm_sec, msTimeSurplus.c_str()); - } - - void PrintLogEx(const char *functionName, int line, uint8_t logLevel, const char *msg, ...) - { - if (logLevel > g_logLevel) { - return; - } - string debugInfo; - string logBuf; - string logLevelString; - string threadIdString; - string sep = "\n"; - string timeString; - - va_list vaArgs; - va_start(vaArgs, msg); - string logDetail = Base::StringFormat(msg, vaArgs); - va_end(vaArgs); - if (logDetail.back() == '\n') { - sep = "\r\n"; - } - debugInfo = functionName; - GetLogDebugFunctioname(debugInfo, line, threadIdString); - GetLogLevelAndTime(logLevel, logLevelString, timeString); - logBuf = StringFormat("[%s][%s]%s%s %s%s", logLevelString.c_str(), timeString.c_str(), threadIdString.c_str(), - debugInfo.c_str(), logDetail.c_str(), sep.c_str()); - - printf("%s", logBuf.c_str()); - fflush(stdout); - // logfile, not thread-safe -#ifdef HDC_SUPPORT_FLASHD - FILE *fp = fopen("/tmp/flashd_hdc.log", "a"); -#else - string path = GetTmpDir() + LOG_FILE_NAME; - FILE *fp = fopen(path.c_str(), "a"); -#endif - if (fp == nullptr) { - return; - } - if (fprintf(fp, "%s", logBuf.c_str()) > 0 && fflush(fp)) { - // make ci happy - } - fclose(fp); - return; - } -#else // else ENABLE_DEBUGLOG.If disabled, the entire output code will be optimized by the compiler - void PrintLogEx(uint8_t logLevel, char *msg, ...) - { - } -#endif // ENABLE_DEBUGLOG - - void PrintMessage(const char *fmt, ...) - { - va_list ap; - va_start(ap, fmt); - if (vfprintf(stdout, fmt, ap) > 0) { - fprintf(stdout, "\n"); - } - va_end(ap); - } - - // if can linkwith -lstdc++fs, use std::filesystem::path(path).filename(); - string GetFileNameAny(string &path) - { - string tmpString = path; - size_t tmpNum = tmpString.rfind('/'); - if (tmpNum == std::string::npos) { - tmpNum = tmpString.rfind('\\'); - if (tmpNum == std::string::npos) { - return tmpString; - } - } - tmpString = tmpString.substr(tmpNum + 1, tmpString.size() - tmpNum); - return tmpString; - } - - int GetMaxBufSize() - { - return MAX_SIZE_IOBUF; - } - - void SetTcpOptions(uv_tcp_t *tcpHandle) - { - constexpr int maxBufFactor = 10; - if (!tcpHandle) { - WRITE_LOG(LOG_WARN, "SetTcpOptions nullptr Ptr"); - return; - } - uv_tcp_keepalive(tcpHandle, 1, GLOBAL_TIMEOUT); - // if MAX_SIZE_IOBUF==5k,bufMaxSize at least 40k. It must be set to io 8 times is more appropriate, - // otherwise asynchronous IO is too fast, a lot of IO is wasted on IOloop, transmission speed will decrease - int bufMaxSize = GetMaxBufSize() * maxBufFactor; - uv_recv_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); - uv_send_buffer_size((uv_handle_t *)tcpHandle, &bufMaxSize); - } - - void ReallocBuf(uint8_t **origBuf, int *nOrigSize, const int indexUsedBuf, int sizeWanted) - { - sizeWanted = GetMaxBufSize(); - int remainLen = *nOrigSize - indexUsedBuf; - // init:0, left less than expected - if (!*nOrigSize || (remainLen < sizeWanted && (*nOrigSize + sizeWanted < sizeWanted * 2))) { - // Memory allocation size is slightly larger than the maximum - int nNewLen = *nOrigSize + sizeWanted + EXTRA_ALLOC_SIZE; - uint8_t *bufPtrOrig = *origBuf; - *origBuf = new uint8_t[nNewLen](); - if (!*origBuf) { - *origBuf = bufPtrOrig; - } else { - *nOrigSize = nNewLen; - if (bufPtrOrig) { - if (memcpy_s(*origBuf, nNewLen, bufPtrOrig, *nOrigSize)) { - WRITE_LOG(LOG_FATAL, "ReallocBuf failed"); - } - delete[] bufPtrOrig; - } - } - uint8_t *buf = static_cast(*origBuf + indexUsedBuf); - Base::ZeroBuf(buf, nNewLen - indexUsedBuf); - } - } - - // As an uv_alloc_cb it must keep the same as prototype - void AllocBufferCallback(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf) - { - const int size = GetMaxBufSize(); - buf->base = (char *)new uint8_t[size](); - if (buf->base) { - buf->len = size - 1; - } - } - - // As an uv_write_cb it must keep the same as prototype - void SendCallback(uv_write_t *req, int status) - { - delete[]((uint8_t *)req->data); - delete req; - } - - // xxx must keep sync with uv_loop_close/uv_walk etc. - bool TryCloseLoop(uv_loop_t *ptrLoop, const char *callerName) - { - // UV_RUN_DEFAULT: Runs the event loop until the reference count drops to zero. Always returns zero. - // UV_RUN_ONCE: Poll for new events once. Note that this function blocks if there are no pending events. - // Returns zero when done (no active handles or requests left), or non-zero if more events are - // expected meaning you should run the event loop again sometime in the future). - // UV_RUN_NOWAIT: Poll for new events once but don't block if there are no pending events. - uint8_t closeRetry = 0; - bool ret = false; - constexpr int maxRetry = 3; - for (closeRetry = 0; closeRetry < maxRetry; ++closeRetry) { - if (uv_loop_close(ptrLoop) == UV_EBUSY) { - if (closeRetry > 2) { // 2 try count - WRITE_LOG(LOG_WARN, "%s close busy,try:%d", callerName, closeRetry); - } - - if (ptrLoop->active_handles >= 2) { - WRITE_LOG(LOG_DEBUG, "TryCloseLoop issue"); - } - auto clearLoopTask = [](uv_handle_t *handle, void *arg) -> void { TryCloseHandle(handle); }; - uv_walk(ptrLoop, clearLoopTask, nullptr); - // If all processing ends, Then return0,this call will block - if (!ptrLoop->active_handles) { - ret = true; - break; - } - if (!uv_run(ptrLoop, UV_RUN_ONCE)) { - ret = true; - break; - } - } else { - ret = true; - break; - } - } - return ret; - } - - // Some handles may not be initialized or activated yet or have been closed, skip the closing process - void TryCloseHandle(const uv_handle_t *handle) - { - TryCloseHandle(handle, nullptr); - } - - void TryCloseHandle(const uv_handle_t *handle, uv_close_cb closeCallBack) - { - TryCloseHandle(handle, false, closeCallBack); - } - - void TryCloseHandle(const uv_handle_t *handle, bool alwaysCallback, uv_close_cb closeCallBack) - { - bool hasCallClose = false; - if (handle->loop && !uv_is_closing(handle)) { - uv_close((uv_handle_t *)handle, closeCallBack); - hasCallClose = true; - } - if (!hasCallClose && alwaysCallback) { - closeCallBack((uv_handle_t *)handle); - } - } - - int SendToStream(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen) - { - if (bufLen > static_cast(HDC_BUF_MAX_BYTES)) { - return ERR_BUF_ALLOC; - } - uint8_t *pDynBuf = new uint8_t[bufLen]; - if (!pDynBuf) { - return ERR_BUF_ALLOC; - } - if (memcpy_s(pDynBuf, bufLen, buf, bufLen)) { - delete[] pDynBuf; - return ERR_BUF_COPY; - } - return SendToStreamEx(handleStream, pDynBuf, bufLen, nullptr, (void *)SendCallback, (void *)pDynBuf); - } - - // handleSend is used for pipe thread sending, set nullptr for tcp, and dynamically allocated by malloc when buf - // is required - int SendToStreamEx(uv_stream_t *handleStream, const uint8_t *buf, const int bufLen, uv_stream_t *handleSend, - const void *finishCallback, const void *pWriteReqData) - { - int ret = -1; - uv_write_t *reqWrite = new uv_write_t(); - if (!reqWrite) { - return 0; - } - uv_buf_t bfr; - while (true) { - reqWrite->data = (void *)pWriteReqData; - bfr.base = (char *)buf; - bfr.len = bufLen; - if (!uv_is_writable(handleStream)) { - delete reqWrite; - break; - } - // handleSend must be a TCP socket or pipe, which is a server or a connection (listening or - // connected state). Bound sockets or pipes will be assumed to be servers. - if (handleSend) { - uv_write2(reqWrite, handleStream, &bfr, 1, handleSend, (uv_write_cb)finishCallback); - } else { - uv_write(reqWrite, handleStream, &bfr, 1, (uv_write_cb)finishCallback); - } - ret = bufLen; - break; - } - return ret; - } - - uint64_t GetRuntimeMSec() - { - struct timespec times = { 0, 0 }; - long time; - clock_gettime(CLOCK_MONOTONIC, ×); - time = times.tv_sec * TIME_BASE + times.tv_nsec / (TIME_BASE * TIME_BASE); - return time; - } - - uint64_t GetRandom(const uint64_t min, const uint64_t max) - { -#ifdef HARMONY_PROJECT - uint64_t ret; - uv_random(nullptr, nullptr, &ret, sizeof(ret), 0, nullptr); -#else - uint64_t ret; - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution dis(min, max); - ret = dis(gen); -#endif - return ret; - } - - string GetRandomString(const uint16_t expectedLen) - { - srand(static_cast(GetRandom())); - string ret = string(expectedLen, '0'); - std::stringstream val; - for (auto i = 0; i < expectedLen; ++i) { - val << std::hex << (rand() % BUF_SIZE_MICRO); - } - ret = val.str(); - return ret; - } - - int GetRandomNum(const int min, const int max) - { - return static_cast(GetRandom(min, max)); - } - - int ConnectKey2IPPort(const char *connectKey, char *outIP, uint16_t *outPort) - { - char bufString[BUF_SIZE_TINY] = ""; - if (memcpy_s(bufString, sizeof(bufString), connectKey, sizeof(bufString))) { - return ERR_BUF_COPY; - } - char *p = strchr(bufString, ':'); - if (!p) { - return ERR_PARM_FORMAT; - } - *p = '\0'; - if (!strlen(bufString) || strlen(bufString) > 16) { - return ERR_PARM_SIZE; - } - uint16_t wPort = static_cast(atoi(p + 1)); - if (EOK != strcpy_s(outIP, BUF_SIZE_TINY, bufString)) { - return ERR_BUF_COPY; - } - *outPort = wPort; - return RET_SUCCESS; - } - - // After creating the session worker thread, execute it on the main thread - void FinishWorkThread(uv_work_t *req, int status) - { - // This is operated in the main thread - delete req; - } - - // at the finsh of pFuncAfterThread must free uv_work_t* - // clang-format off - int StartWorkThread(uv_loop_t *loop, uv_work_cb pFuncWorkThread, - uv_after_work_cb pFuncAfterThread, void *pThreadData) - { - uv_work_t *workThread = new uv_work_t(); - if (!workThread) { - return -1; - } - workThread->data = pThreadData; - uv_queue_work(loop, workThread, pFuncWorkThread, pFuncAfterThread); - return 0; - } - // clang-format on - - char **SplitCommandToArgs(const char *cmdStringLine, int *slotIndex) - { - constexpr int extraBufSize = 2; - char **argv; - char *temp = nullptr; - int argc = 0; - char a = 0; - size_t i = 0; - size_t j = 0; - size_t len = 0; - bool isQuoted = false; - bool isText = false; - bool isSpace = false; - - len = strlen(cmdStringLine); - if (len < 1) { - return nullptr; - } - i = ((len + extraBufSize) / extraBufSize) * sizeof(void *) + sizeof(void *); - argv = reinterpret_cast(new char[i + (len + extraBufSize) * sizeof(char)]); - temp = reinterpret_cast((reinterpret_cast(argv)) + i); - argc = 0; - argv[argc] = temp; - isQuoted = false; - isText = false; - isSpace = true; - i = 0; - j = 0; - - while ((a = cmdStringLine[i]) != 0) { - if (isQuoted) { - if (a == '\"') { - isQuoted = false; - } else { - temp[j] = a; - ++j; - } - } else { - switch (a) { - case '\"': - isQuoted = true; - isText = true; - if (isSpace) { - argv[argc] = temp + j; - ++argc; - } - isSpace = false; - break; - case ' ': - case '\t': - case '\n': - case '\r': - if (isText) { - temp[j] = '\0'; - ++j; - } - isText = false; - isSpace = true; - break; - default: - isText = true; - if (isSpace) { - argv[argc] = temp + j; - ++argc; - } - temp[j] = a; - ++j; - isSpace = false; - break; - } - } - ++i; - } - temp[j] = '\0'; - argv[argc] = nullptr; - - (*slotIndex) = argc; - return argv; - } - - bool RunPipeComand(const char *cmdString, char *outBuf, uint16_t sizeOutBuf, bool ignoreTailLf) - { - FILE *pipeHandle = popen(cmdString, "r"); - if (pipeHandle == nullptr) { - return false; - } - int bytesRead = 0; - int bytesOnce = 0; - while (!feof(pipeHandle)) { - bytesOnce = fread(outBuf, 1, sizeOutBuf - bytesRead, pipeHandle); - if (bytesOnce <= 0) { - break; - } - bytesRead += bytesOnce; - } - if (bytesRead && ignoreTailLf) { - if (outBuf[bytesRead - 1] == '\n') { - outBuf[bytesRead - 1] = '\0'; - } - } - pclose(pipeHandle); - return bytesRead; - } - - bool SetHdcProperty(const char *key, const char *value) - { -#ifndef __MUSL__ -#ifdef HDC_PCDEBUG - WRITE_LOG(LOG_DEBUG, "Setproperty, key:%s value:%s", key, value); -#else - string sKey = key; - string sValue = value; - string sBuf = "setprop " + sKey + " " + value; - system(sBuf.c_str()); -#endif -#else - SetParameter(key, value); -#endif - return true; - } - - bool GetHdcProperty(const char *key, char *value, uint16_t sizeOutBuf) - { -#ifndef __MUSL__ -#ifdef HDC_PCDEBUG - WRITE_LOG(LOG_DEBUG, "Getproperty, key:%s value:%s", key, value); -#else - string sKey = key; - string sBuf = "getprop " + sKey; - RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); -#endif -#else - string sKey = key; - string sBuf = "param get " + sKey; - RunPipeComand(sBuf.c_str(), value, sizeOutBuf, true); -#endif - value[sizeOutBuf - 1] = '\0'; - return true; - } - - // bufLen == 0: alloc buffer in heap, need free it later - // >0: read max nBuffLen bytes to *buff - // ret value: <0 or bytes read - int ReadBinFile(const char *pathName, void **buf, const int bufLen) - { - uint8_t *pDst = nullptr; - int byteIO = 0; - struct stat statbuf; - int ret = stat(pathName, &statbuf); - if (ret < 0) { - return -1; - } - int nFileSize = statbuf.st_size; - int readMax = 0; - uint8_t dynamicBuf = 0; - ret = -3; - if (bufLen == 0) { - dynamicBuf = 1; - pDst = new uint8_t[nFileSize + 1](); // tail \0 - if (!pDst) { - return -1; - } - readMax = nFileSize; - } else { - if (nFileSize > bufLen) { - return -2; - } - readMax = nFileSize; - pDst = reinterpret_cast(buf); // The first address of the static array is the array address - } - - string srcPath(pathName); - string resolvedPath = CanonicalizeSpecPath(srcPath); - FILE *fp = fopen(resolvedPath.c_str(), "r"); - if (fp == nullptr) { - goto ReadFileFromPath_Finish; - } - byteIO = fread(pDst, 1, readMax, fp); - fclose(fp); - if (byteIO != readMax) { - goto ReadFileFromPath_Finish; - } - ret = 0; - ReadFileFromPath_Finish: - if (ret) { - if (dynamicBuf) { - delete[] pDst; - } - } else { - if (dynamicBuf) { - *buf = pDst; - } - ret = byteIO; - } - return ret; - } - - int WriteBinFile(const char *pathName, const uint8_t *buf, const int bufLen, bool newFile) - { - string mode; - string resolvedPath; - string srcPath(pathName); - if (newFile) { - mode = "wb+"; - // no std::fs supoort, else std::filesystem::canonical,-lstdc++fs - if (srcPath.find("..") != string::npos) { - return ERR_FILE_PATH_CHECK; - } - resolvedPath = srcPath.c_str(); - } else { - mode = "a+"; - resolvedPath = CanonicalizeSpecPath(srcPath); - } - FILE *fp = fopen(resolvedPath.c_str(), mode.c_str()); - if (fp == nullptr) { - WRITE_LOG(LOG_DEBUG, "Write to %s failed!", pathName); - return ERR_FILE_OPEN; - } - int bytesDone = fwrite(buf, 1, bufLen, fp); - fflush(fp); - fclose(fp); - if (bytesDone != bufLen) { - return ERR_BUF_SIZE; - } - return RET_SUCCESS; - } - - void CloseIdleCallback(uv_handle_t *handle) - { - delete (uv_idle_t *)handle; - }; - - void CloseTimerCallback(uv_handle_t *handle) - { - delete (uv_timer_t *)handle; - }; - - // return value: <0 error; 0 can start new server instance; >0 server already exists - int ProgramMutex(const char *procname, bool checkOrNew) - { - char bufPath[BUF_SIZE_DEFAULT] = ""; - char buf[BUF_SIZE_DEFAULT] = ""; - char pidBuf[BUF_SIZE_TINY] = ""; - size_t size = sizeof(buf); - if (uv_os_tmpdir(buf, &size) < 0) { - WRITE_LOG(LOG_FATAL, "Tmppath failed"); - return ERR_API_FAIL; - } - if (snprintf_s(bufPath, sizeof(bufPath), sizeof(bufPath) - 1, "%s%c.%s.pid", buf, Base::GetPathSep(), procname) - < 0) { - return ERR_BUF_OVERFLOW; - } - int pid = static_cast(getpid()); - if (snprintf_s(pidBuf, sizeof(pidBuf), sizeof(pidBuf) - 1, "%d", pid) < 0) { - return ERR_BUF_OVERFLOW; - } - // no need to CanonicalizeSpecPath, else not work - umask(0); - int fd = open(bufPath, O_RDWR | O_CREAT, 0666); // 0666:permission - if (fd < 0) { - WRITE_LOG(LOG_FATAL, "Open mutex file \"%s\" failed!!!Errno:%d\n", buf, errno); - return ERR_FILE_OPEN; - } -#ifdef _WIN32 - if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "Global\\%s", procname) < 0) { - return ERR_BUF_OVERFLOW; - } - HANDLE hMutex = CreateMutex(nullptr, FALSE, buf); - DWORD dwError = GetLastError(); - if (ERROR_ALREADY_EXISTS == dwError || ERROR_ACCESS_DENIED == dwError) { - WRITE_LOG(LOG_DEBUG, "File \"%s\" locked. proc already exit!!!\n", procname); - return 1; - } - if (checkOrNew) { - CloseHandle(hMutex); - } -#else - struct flock fl; - fl.l_type = F_WRLCK; - fl.l_start = 0; - fl.l_whence = SEEK_SET; - fl.l_len = 0; - int retChild = fcntl(fd, F_SETLK, &fl); - if (-1 == retChild) { - WRITE_LOG(LOG_DEBUG, "File \"%s\" locked. proc already exit!!!\n", bufPath); - close(fd); - return 1; - } -#endif - ftruncate(fd, 0); - write(fd, pidBuf, strlen(pidBuf) + 1); - WRITE_LOG(LOG_DEBUG, "Write mutext to %s, pid:%s", bufPath, pidBuf); - if (checkOrNew) { - // close it for check only - close(fd); - } - // Do not close the file descriptor, the process will be mutext effect under no-Win32 OS - return RET_SUCCESS; - } - - void SplitString(const string &origString, const string &seq, vector &resultStrings) - { - string::size_type p1 = 0; - string::size_type p2 = origString.find(seq); - - while (p2 != string::npos) { - if (p2 == p1) { - ++p1; - p2 = origString.find(seq, p1); - continue; - } - resultStrings.push_back(origString.substr(p1, p2 - p1)); - p1 = p2 + seq.size(); - p2 = origString.find(seq, p1); - } - - if (p1 != origString.size()) { - resultStrings.push_back(origString.substr(p1)); - } - } - - string GetShellPath() - { - struct stat filecheck; - string shellPath = "/bin/sh"; - if (stat(shellPath.c_str(), &filecheck) < 0) { - shellPath = "/system/bin/sh"; - if (stat(shellPath.c_str(), &filecheck) < 0) { - shellPath = "sh"; - } - } - return shellPath; - } - - // Not supported on some platforms, Can only be achieved manually - uint64_t HostToNet(uint64_t val) - { - if (htonl(1) == 1) - return val; - return (((uint64_t)htonl(val)) << 32) + htonl(val >> 32); - } - - uint64_t NetToHost(uint64_t val) - { - if (htonl(1) == 1) - return val; - return (((uint64_t)ntohl(val)) << 32) + ntohl(val >> 32); - } - - char GetPathSep() - { -#ifdef _WIN32 - const char sep = '\\'; -#else - const char sep = '/'; -#endif - return sep; - } - - string GetFullFilePath(const string &s) - { // cannot use s.rfind(std::filesystem::path::preferred_separator - size_t i = s.rfind(GetPathSep(), s.length()); - if (i != string::npos) { - return (s.substr(i + 1, s.length() - i)); - } - return s; - } - - int CreateSocketPair(int *fds) - { -#ifndef _WIN32 -#ifdef HOST_MAC - int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); - if (ret == 0) { - for (auto i = 0; i < 2; ++i) { - if (fcntl(fds[i], F_SETFD, FD_CLOEXEC) == -1) { - close(fds[0]); - close(fds[1]); - WRITE_LOG(LOG_WARN, "fcntl failed to set FD_CLOEXEC: %s", strerror(errno)); - return -1; - } - } - } - return ret; -#else - return socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds); -#endif -#else - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); - int reuse = 1; - if (fds == 0) { - return -1; - } - int listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (listener == -1) { - return -2; - } - Base::ZeroStruct(addr); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - addr.sin_port = 0; - fds[0] = fds[1] = (int)-1; - do { - if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, (socklen_t)sizeof(reuse))) { - break; - } - if (::bind(listener, (struct sockaddr *)&addr, sizeof(addr))) { - break; - } - if (getsockname(listener, (struct sockaddr *)&addr, &addrlen)) { - break; - } - if (listen(listener, 1)) { - break; - } - fds[0] = socket(AF_INET, SOCK_STREAM, 0); - if (fds[0] == -1) { - break; - } - if (connect(fds[0], (struct sockaddr *)&addr, sizeof(addr)) == -1) { - break; - } - fds[1] = accept(listener, nullptr, nullptr); - if (fds[1] == -1) { - break; - } - closesocket(listener); - return 0; - } while (0); - - closesocket(listener); - closesocket(fds[0]); - closesocket(fds[1]); - return -1; -#endif - } - - void CloseSocketPair(const int *fds) - { -#ifndef _WIN32 - close(fds[0]); - close(fds[1]); -#else - closesocket(fds[0]); - closesocket(fds[1]); -#endif - } - - int StringEndsWith(string s, string sub) - { - return s.rfind(sub) == (s.length() - sub.length()) ? 1 : 0; - } - - // Both absolute and relative paths support - bool CheckDirectoryOrPath(const char *localPath, bool pathOrDir, bool readWrite) - { - if (pathOrDir) { // filepath - uv_fs_t req; - int r = uv_fs_lstat(nullptr, &req, localPath, nullptr); - uv_fs_req_cleanup(&req); - if (r == 0 && req.statbuf.st_mode & S_IFREG) { // is file - uv_fs_access(nullptr, &req, localPath, readWrite ? R_OK : W_OK, nullptr); - uv_fs_req_cleanup(&req); - if (req.result == 0) - return true; - } - } else { // dir - } - return false; - } - - // Using openssl encryption and decryption method, high efficiency; when encrypting more than 64 bytes, - // the carriage return will not be added, and the tail padding 00 is removed when decrypting - // The return value is the length of the string after Base64 - int Base64EncodeBuf(const uint8_t *input, const int length, uint8_t *bufOut) - { - return EVP_EncodeBlock(bufOut, input, length); - } - - vector Base64Encode(const uint8_t *input, const int length) - { - vector retVec; - uint8_t *pBuf = nullptr; - while (true) { - if (static_cast(length) > HDC_BUF_MAX_BYTES) { - break; - } - int base64Size = length * 1.4 + 256; - if (!(pBuf = new uint8_t[base64Size]())) { - break; - } - int childRet = Base64EncodeBuf(input, length, pBuf); - if (childRet <= 0) { - break; - } - retVec.insert(retVec.begin(), pBuf, pBuf + childRet); - break; - } - if (pBuf) { - delete[] pBuf; - } - - return retVec; - } - - inline int CalcDecodeLength(const uint8_t *b64input) - { - int len = strlen(reinterpret_cast(const_cast(b64input))); - if (!len) { - return 0; - } - int padding = 0; - if (b64input[len - 1] == '=' && b64input[len - 2] == '=') { - // last two chars are = - padding = 2; // 2 : last two chars - } else if (b64input[len - 1] == '=') { - // last char is = - padding = 1; - } - return static_cast(len * 0.75 - padding); - } - - // return -1 error; >0 decode size - int Base64DecodeBuf(const uint8_t *input, const int length, uint8_t *bufOut) - { - int nRetLen = CalcDecodeLength(input); - if (!nRetLen) { - return 0; - } - - if (EVP_DecodeBlock(bufOut, input, length) > 0) { - return nRetLen; - } - return 0; - } - - string Base64Decode(const uint8_t *input, const int length) - { - string retString; - uint8_t *pBuf = nullptr; - while (true) { - if ((uint32_t)length > HDC_BUF_MAX_BYTES) { - break; - } - // must less than length - if (!(pBuf = new uint8_t[length]())) { - break; - } - int childRet = Base64DecodeBuf(input, length, pBuf); - if (childRet <= 0) { - break; - } - retString = (reinterpret_cast(pBuf)); - break; - } - if (pBuf) { - delete[] pBuf; - } - return retString; - } - - void ReverseBytes(void *start, int size) - { - uint8_t *istart = (uint8_t *)start; - uint8_t *iend = istart + size; - std::reverse(istart, iend); - } - - // clang-format off - const string StringFormat(const char * const formater, ...) - { - va_list vaArgs; - va_start(vaArgs, formater); - string ret = StringFormat(formater, vaArgs); - va_end(vaArgs); - return ret; - } - - const string StringFormat(const char * const formater, va_list &vaArgs) - { - std::vector args(MAX_SIZE_IOBUF); - const int retSize = vsnprintf_s(args.data(), MAX_SIZE_IOBUF, args.size() - 1, formater, vaArgs); - if (retSize < 0) { - return std::string(""); - } else { - return std::string(args.data(), retSize); - } - } - // clang-format on - - string GetVersion() - { - const uint8_t a = 'a'; - uint8_t major = (HDC_VERSION_NUMBER >> 28) & 0xff; - uint8_t minor = (HDC_VERSION_NUMBER << 4 >> 24) & 0xff; - uint8_t version = (HDC_VERSION_NUMBER << 12 >> 24) & 0xff; - uint8_t fix = (HDC_VERSION_NUMBER << 20 >> 28) & 0xff; // max 16, tail is p - string ver = StringFormat("%x.%x.%x%c", major, minor, version, a + fix); - return "Ver: " + ver; - } - - bool IdleUvTask(uv_loop_t *loop, void *data, uv_idle_cb cb) - { - uv_idle_t *idle = new uv_idle_t(); - if (idle == nullptr) { - return false; - } - idle->data = data; - uv_idle_init(loop, idle); - uv_idle_start(idle, cb); - // delete by callback - return true; - } - - bool TimerUvTask(uv_loop_t *loop, void *data, uv_timer_cb cb, int repeatTimeout) - { - uv_timer_t *timer = new uv_timer_t(); - if (timer == nullptr) { - return false; - } - timer->data = data; - uv_timer_init(loop, timer); - uv_timer_start(timer, cb, 0, repeatTimeout); - // delete by callback - return true; - } - - // callback, uint8_t flag, string msg, const void * data - bool DelayDo(uv_loop_t *loop, const int delayMs, const uint8_t flag, string msg, void *data, - std::function cb) - { - struct DelayDoParam { - uv_timer_t handle; - uint8_t flag; - string msg; - void *data; - std::function cb; - }; - auto funcDelayDo = [](uv_timer_t *handle) -> void { - DelayDoParam *st = (DelayDoParam *)handle->data; - st->cb(st->flag, st->msg, st->data); - uv_close((uv_handle_t *)handle, [](uv_handle_t *handle) { - DelayDoParam *st = (DelayDoParam *)handle->data; - delete st; - }); - }; - DelayDoParam *st = new DelayDoParam(); - if (st == nullptr) { - return false; - } - st->cb = cb; - st->flag = flag; - st->msg = msg; - st->data = data; - st->handle.data = st; - uv_timer_init(loop, &st->handle); - uv_timer_start(&st->handle, funcDelayDo, delayMs, 0); - return true; - } - - string ReplaceAll(string str, const string from, const string to) - { - string::size_type startPos = 0; - while ((startPos = str.find(from, startPos)) != string::npos) { - str.replace(startPos, from.length(), to); - startPos += to.length(); // Handles case where 'to' is a substring of 'from' - } - return str; - } - - string CanonicalizeSpecPath(string &src) - { - char resolvedPath[PATH_MAX] = { 0 }; -#if defined(_WIN32) - if (!_fullpath(resolvedPath, src.c_str(), PATH_MAX)) { - WRITE_LOG(LOG_FATAL, "_fullpath %s failed", src.c_str()); - return ""; - } -#else - if (realpath(src.c_str(), resolvedPath) == nullptr) { - WRITE_LOG(LOG_FATAL, "realpath %s failed", src.c_str()); - return ""; - } -#endif - string res(resolvedPath); - return res; - } - - uint8_t CalcCheckSum(const uint8_t *data, int len) - { - uint8_t ret = 0; - for (int i = 0; i < len; ++i) { - ret += data[i]; - } - return ret; - } - - int open_osfhandle(uv_os_fd_t os_fd) - { - // equal libuv's uv_open_osfhandle, libuv 1.23 added. old libuv not impl... -#ifdef _WIN32 - return _open_osfhandle((intptr_t)os_fd, 0); -#else - return os_fd; -#endif - } - - uv_os_sock_t DuplicateUvSocket(uv_tcp_t *tcp) - { - uv_os_sock_t dupFd = -1; -#ifdef _WIN32 - WSAPROTOCOL_INFO info; - ZeroStruct(info); - if (WSADuplicateSocketA(tcp->socket, GetCurrentProcessId(), &info) < 0) { - return dupFd; - } - dupFd = WSASocketA(0, 0, 0, &info, 0, 0); -#else - uv_os_fd_t fdOs; - if (uv_fileno((const uv_handle_t *)tcp, &fdOs) < 0) { - return ERR_API_FAIL; - } - dupFd = dup(open_osfhandle(fdOs)); -#endif - return dupFd; - } - - vector Md5Sum(uint8_t *buf, int size) - { - vector ret; - uint8_t md5Hash[MD5_DIGEST_LENGTH] = { 0 }; - if (EVP_Digest(buf, size, md5Hash, NULL, EVP_md5(), NULL)) { - ret.insert(ret.begin(), md5Hash, md5Hash + sizeof(md5Hash)); - } - return ret; - } - - string GetCwd() - { - char path[PATH_MAX] = ""; - size_t size = sizeof(path); - string res; - if (uv_cwd(path, &size) < 0) { - return res; - } - if (path[strlen(path) - 1] != Base::GetPathSep()) { - path[strlen(path)] = Base::GetPathSep(); - } - res = path; - return res; - } - - string GetTmpDir() - { - string res; -#ifdef HDC_HOST - char path[PATH_MAX] = ""; - size_t size = sizeof(path); - if (uv_os_tmpdir(path, &size) < 0) { - WRITE_LOG(LOG_FATAL, "get tmppath failed!"); - return res; - } - if (path[strlen(path) - 1] != Base::GetPathSep()) { - path[strlen(path)] = Base::GetPathSep(); - } - res = path; -#else - res = "/data/local/tmp/"; -#endif - return res; - } - - bool IsRoot() - { -#ifdef _WIN32 - // reserve - return true; -#else - if (getuid() == 0) { - return true; - } -#endif - return false; - } - - bool IsAbsolutePath(string &path) - { - bool ret = false; -#ifdef _WIN32 - // shlwapi.h PathIsRelativeA not link in harmony project - // c:\ or UNC path '\\hostname\share\file' - ret = path.find(":\\") == 1 || path.find("\\\\") == 0; -#else - ret = path[0] == '/'; -#endif - return ret; - } -} -} // namespace Hdc diff --git a/services/flashd/daemon/daemon_unity.cpp b/services/flashd/daemon/daemon_unity.cpp index 5a4aa067..cbe17806 100755 --- a/services/flashd/daemon/daemon_unity.cpp +++ b/services/flashd/daemon/daemon_unity.cpp @@ -15,9 +15,7 @@ #include "daemon_unity.h" #include #ifdef __MUSL__ -extern "C" { #include "init_reboot.h" -} #endif namespace Hdc { diff --git a/services/flashd/host/client.cpp b/services/flashd/host/client.cpp index a1b93bcd..b2877c6b 100755 --- a/services/flashd/host/client.cpp +++ b/services/flashd/host/client.cpp @@ -168,7 +168,7 @@ int HdcClient::ExecuteCommand(const string &commandIn) ConnectServerForClient(ip, port); uv_timer_init(loopMain, &waitTimeDoCmd); waitTimeDoCmd.data = this; - uv_timer_start(&waitTimeDoCmd, CommandWorker, 10, 10); + uv_timer_start(&waitTimeDoCmd, CommandWorker, 10, 10); // 10 10 repeat WorkerPendding(); return 0; } diff --git a/services/flashd/host/main.cpp b/services/flashd/host/main.cpp index 878428c7..3fe5d5b8 100755 --- a/services/flashd/host/main.cpp +++ b/services/flashd/host/main.cpp @@ -175,7 +175,7 @@ bool ParseServerListenString(string &serverListenString, char *optarg) } char *p = strchr(buf, ':'); if (!p) { // Only port - if (strlen(buf) > 5) { // port len + if (strlen(buf) > 5) { // 5 port len Base::PrintMessage("The port-string's length must < 5"); return false; } -- Gitee From f5a2b8ef89ee71a0d1ce809396abe385b754f29e Mon Sep 17 00:00:00 2001 From: Jinguang Dong Date: Fri, 19 Nov 2021 16:50:32 +0800 Subject: [PATCH 58/94] Description:[fix] Remove useless opensource notice information for libsparse Bug: #I4J004 Test: Could not find the useless notice information for libsparse Signed-off-by: Jinguang Dong --- LICENSE | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/LICENSE b/LICENSE index a3a34c88..a2f26205 100755 --- a/LICENSE +++ b/LICENSE @@ -11,22 +11,6 @@ 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. -*************************************************************** -libsparse, it is derived from the following: -https://android.googlesource.com/platform/system/core/ -version 10.0.0_r2 -*************************************************************** -Copyright (C) 2012, The Android Open Source Project - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. - -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. - *************************************************************** bsdiff, it is derived from the following: @@ -235,4 +219,4 @@ version 4.3 incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - END OF TERMS AND CONDITIONS \ No newline at end of file + END OF TERMS AND CONDITIONS -- Gitee From d4d67ca7d2a0108273f7cbd2061a399f6872b9a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E4=BC=9F=E6=B0=91?= Date: Thu, 2 Dec 2021 17:18:23 +0800 Subject: [PATCH 59/94] fix: fix the bug that the return value still be success when original size error in the PkgAlgorithm::Pack. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 张伟民 --- services/package/pkg_algorithm/pkg_algorithm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/package/pkg_algorithm/pkg_algorithm.cpp b/services/package/pkg_algorithm/pkg_algorithm.cpp index c65548ca..1062b4fa 100644 --- a/services/package/pkg_algorithm/pkg_algorithm.cpp +++ b/services/package/pkg_algorithm/pkg_algorithm.cpp @@ -78,7 +78,7 @@ int32_t PkgAlgorithm::Pack(const PkgStreamPtr inStream, const PkgStreamPtr outSt ret = FinalDigest(algorithm, context, true); PKG_CHECK(ret == 0, return ret, "Check digest fail"); - PKG_CHECK(srcOffset - context.srcOffset == context.unpackedSize, return ret, + PKG_CHECK(srcOffset - context.srcOffset == context.unpackedSize, return PKG_INVALID_STREAM, "original size error %zu %zu", srcOffset, context.unpackedSize); context.packedSize = destOffset - context.destOffset; return ret; -- Gitee From 9e32cc6a9b8af180960db002b928ad527463592a Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Fri, 3 Dec 2021 13:44:26 +0800 Subject: [PATCH 60/94] updater: fix codedex Signed-off-by: xionglei6 --- services/diffpatch/diff/blocks_diff.cpp | 4 +-- services/flashd/daemon/daemon.cpp | 4 +-- services/flashd/daemon/daemon_unity.cpp | 7 +++--- services/flashd/host/host_updater.cpp | 4 ++- services/flashd/host/main.cpp | 25 +++---------------- services/flashd/host/server.cpp | 3 +-- services/flashd/host/server_for_client.cpp | 5 ++-- services/flashd/host/translate.cpp | 4 +-- services/updater_utils.cpp | 7 +++--- .../DoPartitions_fuzzer.cpp | 3 ++- .../UpdaterFactoryReset_fuzzer.cpp | 3 ++- .../flashd_test/flash_host_unittest.cpp | 4 +++ .../unittest/package/pkg_package_unittest.cpp | 12 +-------- test/unittest/package/pkg_test.h | 1 - 14 files changed, 32 insertions(+), 54 deletions(-) diff --git a/services/diffpatch/diff/blocks_diff.cpp b/services/diffpatch/diff/blocks_diff.cpp index 2a68f28c..d579dbd9 100644 --- a/services/diffpatch/diff/blocks_diff.cpp +++ b/services/diffpatch/diff/blocks_diff.cpp @@ -237,7 +237,7 @@ void BlocksDiff::ComputeLength(const BlockBuffer &newInfo, int64_t i = 0; int64_t s = 0; int64_t tmp = 0; - for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length));) { + for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length)); ) { if (oldInfo.buffer[lastPos_ + i] == newInfo.buffer[lastScan_ + i]) { s++; } @@ -413,7 +413,7 @@ void SuffixArray::Init(const BlockBuffer &oldInfo) DataType len = 0; for (h = 1; suffixArray_[0] != -(static_cast(oldInfo.length) + 1); h += h) { len = 0; - for (i = 0; i < (static_cast(oldInfo.length) + 1);) { + for (i = 0; i < (static_cast(oldInfo.length) + 1); ) { if (suffixArray_[i] < 0) { len -= suffixArray_[i]; i -= suffixArray_[i]; diff --git a/services/flashd/daemon/daemon.cpp b/services/flashd/daemon/daemon.cpp index fcf55dfa..d3e1d09b 100755 --- a/services/flashd/daemon/daemon.cpp +++ b/services/flashd/daemon/daemon.cpp @@ -161,8 +161,8 @@ bool HdcDaemon::HandDaemonAuth(HSession hSession, const uint32_t channelId, Sess // jump out dialog, and click the system, the system will store the Host public key certificate in the // device locally, and the signature authentication will be correct when the subsequent connection is // connected. - if (!HdcAuth::AuthVerify((uint8_t *)hSession->tokenRSA.c_str(), (uint8_t *)handshake.buf.c_str(), - handshake.buf.size())) { + if (!HdcAuth::AuthVerify((uint8_t *)hSession->tokenRSA.c_str(), + (uint8_t *)handshake.buf.c_str(), handshake.buf.size())) { // Next auth handshake.authType = AUTH_TOKEN; handshake.buf = hSession->tokenRSA; diff --git a/services/flashd/daemon/daemon_unity.cpp b/services/flashd/daemon/daemon_unity.cpp index cbe17806..cd4f3ffe 100755 --- a/services/flashd/daemon/daemon_unity.cpp +++ b/services/flashd/daemon/daemon_unity.cpp @@ -72,11 +72,10 @@ bool HdcDaemonUnity::AsyncCmdOut(bool finish, int64_t exitStatus, const string r int HdcDaemonUnity::ExecuteShell(const char *shellCommand) { do { - AsyncCmd::CmdResultCallback funcResultOutput; - funcResultOutput = std::bind(&HdcDaemonUnity::AsyncCmdOut, this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3); + AsyncCmd::CmdResultCallback funcResultOutput = std::bind(&HdcDaemonUnity::AsyncCmdOut, + this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); if (!asyncCommand.Initial(loopTask, funcResultOutput, - asyncCommand.GetDefaultOption() | asyncCommand.OPTION_READBACK_OUT)) { + asyncCommand.GetDefaultOption() | asyncCommand.OPTION_READBACK_OUT)) { break; } asyncCommand.ExecuteCommand(shellCommand); diff --git a/services/flashd/host/host_updater.cpp b/services/flashd/host/host_updater.cpp index 9cd19ffb..0b4cd69b 100755 --- a/services/flashd/host/host_updater.cpp +++ b/services/flashd/host/host_updater.cpp @@ -20,7 +20,7 @@ #include "transfer.h" #include "serial_struct.h" -namespace Hdc { +namespace { static const std::string helpCmd = "flash"; static const std::string updateCmd = "update "; static const std::string flashCmd = "flash "; @@ -28,6 +28,8 @@ static const std::string eraseCmd = "erase "; static const std::string formatCmd = "format "; static const int PERCENT_FINISH = 100; static const uint32_t PERCENT_CLEAR = ((uint32_t)-1); +} +namespace Hdc { HostUpdater::HostUpdater(HTaskInfo hTaskInfo) : HdcTransferBase(hTaskInfo) { commandBegin = CMD_UPDATER_BEGIN; diff --git a/services/flashd/host/main.cpp b/services/flashd/host/main.cpp index 3fe5d5b8..d1dad994 100755 --- a/services/flashd/host/main.cpp +++ b/services/flashd/host/main.cpp @@ -31,7 +31,7 @@ namespace Hdc { // return value: 0 == not command, 1 == one command, 2 == double command int IsRegisterCommand(string &outCommand, const char *cmd, const char *cmdnext) { - string sCmdNext = cmdnext == nullptr ? string("") : string(cmdnext); + string sCmdNext = (cmdnext == nullptr) ? string("") : string(cmdnext); string doubleCommand = cmd + string(" ") + sCmdNext; vector registerCommand; registerCommand.push_back(CMDSTR_SOFTWARE_VERSION); @@ -76,7 +76,7 @@ void AppendCwdWhenTransfer(string &outCommand) if (path[strlen(path) - 1] != Base::GetPathSep()) { path[strlen(path)] = Base::GetPathSep(); } - outCommand += outCommand.size() ? " -cwd " : "-cwd "; + outCommand = outCommand + (outCommand.size() ? " -cwd " : "-cwd "); outCommand += path; } @@ -121,21 +121,6 @@ int RunServerMode(string &serverListenString) return 0; } -int RunPcDebugMode(bool isPullServer, bool isTCPorUSB, int isTestMethod) -{ - pthread_t pt; - if (isPullServer) { - pthread_create(&pt, nullptr, TestBackgroundServerForClient, nullptr); - uv_sleep(200); // give time to start serverForClient,at least 200ms - } - TestRuntimeCommandSimple(isTCPorUSB, isTestMethod, true); - if (isPullServer) { - pthread_join(pt, nullptr); - WRITE_LOG(LOG_DEBUG, "!!!!!!!!!Server finish"); - } - return 0; -} - int RunClientMode(string &commands, string &serverListenString, string &connectKey, bool isPullServer) { uv_loop_t loopMain; @@ -205,7 +190,7 @@ bool GetCommandlineOptions(int optArgc, const char *optArgv[]) bool needExit = false; opterr = 0; // get option parameters first - while ((ch = getopt(optArgc, (char *const *)optArgv, "hvpfms:d:t:l:")) != -1) { + while ((ch = getopt(optArgc, (char* const *)optArgv, "hvpfms:d:t:l:")) != -1) { switch (ch) { case 'h': { string usage = Hdc::TranslateCommand::Usage(); @@ -302,9 +287,7 @@ int main(int argc, const char *argv[]) // -m server.Run alone in the background, no -s will be listen loopback address, Base::SetLogLevel(g_logLevel); // default level LOG_LEVEL_FULL Hdc::RunServerMode(g_serverListenString); - } else if (g_isPcDebugRun) { - Hdc::RunPcDebugMode(g_isPullServer, g_isTCPorUSB, g_isTestMethod); - } else { + } else if (!g_isPcDebugRun) { Hdc::RunClientMode(commands, g_serverListenString, g_connectKey, g_isPullServer); } WRITE_LOG(LOG_DEBUG, "!!!!!!!!!Main finish main"); diff --git a/services/flashd/host/server.cpp b/services/flashd/host/server.cpp index 1d8097bc..da4d8a1d 100755 --- a/services/flashd/host/server.cpp +++ b/services/flashd/host/server.cpp @@ -157,9 +157,8 @@ bool HdcServer::PullupServer(const char *listenString) void HdcServer::ClearMapDaemonInfo() { - map::iterator iter; uv_rwlock_rdlock(&daemonAdmin); - for (iter = mapDaemon.begin(); iter != mapDaemon.end();) { + for (auto iter = mapDaemon.begin(); iter != mapDaemon.end();) { string sKey = iter->first; HDaemonInfo hDi = iter->second; delete hDi; diff --git a/services/flashd/host/server_for_client.cpp b/services/flashd/host/server_for_client.cpp index 496b0bbf..2cbf9228 100755 --- a/services/flashd/host/server_for_client.cpp +++ b/services/flashd/host/server_for_client.cpp @@ -188,7 +188,7 @@ void HdcServerForClient::OrderConnecTargetResult(uv_timer_t *req) bool bExitRepet = false; HDaemonInfo hdi = nullptr; string sRet; - string target = std::string(hChannel->bufStd + 2); + string target = std::string(hChannel->bufStd + 2); // 2 len if (target == "any") { ptrServer->AdminDaemonMap(OP_GET_ANY, target, hdi); } else { @@ -466,8 +466,7 @@ bool HdcServerForClient::DoCommandRemote(HChannel hChannel, void *formatCommandI case CMD_UNITY_ROOTRUN: case CMD_UNITY_JPID: { if (!SendToDaemon(hChannel, formatCommand->cmdFlag, - reinterpret_cast(const_cast(formatCommand->parameters.c_str())), - sizeSend)) { + reinterpret_cast(const_cast(formatCommand->parameters.c_str())), sizeSend)) { break; } ret = true; diff --git a/services/flashd/host/translate.cpp b/services/flashd/host/translate.cpp index 5b274307..dc7bc09d 100755 --- a/services/flashd/host/translate.cpp +++ b/services/flashd/host/translate.cpp @@ -182,8 +182,8 @@ namespace TranslateCommand { outCmd->cmdFlag = CMD_FILE_INIT; outCmd->parameters = input.c_str() + 5; // 5: CMDSTR_FORWARD_FPORT CMDSTR_FORWARD_RPORT size } else if (!strncmp(input.c_str(), string(CMDSTR_FORWARD_FPORT + " ").c_str(), CMDSTR_FORWARD_FPORT.size() + 1) - || !strncmp(input.c_str(), string(CMDSTR_FORWARD_RPORT + " ").c_str(), - CMDSTR_FORWARD_RPORT.size() + 1)) { + || !strncmp(input.c_str(), string(CMDSTR_FORWARD_RPORT + " ").c_str(), + CMDSTR_FORWARD_RPORT.size() + 1)) { stringError = ForwardPort(input.c_str(), outCmd); } else if (!strcmp(input.c_str(), CMDSTR_KILL_SERVER.c_str())) { outCmd->cmdFlag = CMD_KERNEL_SERVER_KILL; diff --git a/services/updater_utils.cpp b/services/updater_utils.cpp index bd4e7927..dc928c74 100755 --- a/services/updater_utils.cpp +++ b/services/updater_utils.cpp @@ -30,12 +30,13 @@ #include "updater_ui.h" #include "utils.h" +namespace { +static constexpr int USER_ROOT_AUTHORITY = 0; +static constexpr int GROUP_SYS_AUTHORITY = 1000; +} namespace updater { using namespace hpackage; using namespace updater::utils; -static constexpr int USER_ROOT_AUTHORITY = 0; -static constexpr int GROUP_SYS_AUTHORITY = 1000; - void CompressLogs(const std::string &name) { PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); diff --git a/test/fuzztest/DoPartitions_fuzzer/DoPartitions_fuzzer.cpp b/test/fuzztest/DoPartitions_fuzzer/DoPartitions_fuzzer.cpp index 48ea89d7..7a941b3b 100644 --- a/test/fuzztest/DoPartitions_fuzzer/DoPartitions_fuzzer.cpp +++ b/test/fuzztest/DoPartitions_fuzzer/DoPartitions_fuzzer.cpp @@ -26,8 +26,9 @@ #include "securec.h" using namespace updater; +namespace { static constexpr int FSTAB_NAME_LENGTH = 20; - +} static void InitEmmcPartition(struct Partition &part, const std::string &partName, size_t start, size_t length) { part.partName = partName; diff --git a/test/fuzztest/UpdaterFactoryReset_fuzzer/UpdaterFactoryReset_fuzzer.cpp b/test/fuzztest/UpdaterFactoryReset_fuzzer/UpdaterFactoryReset_fuzzer.cpp index db10a9b6..60e10961 100644 --- a/test/fuzztest/UpdaterFactoryReset_fuzzer/UpdaterFactoryReset_fuzzer.cpp +++ b/test/fuzztest/UpdaterFactoryReset_fuzzer/UpdaterFactoryReset_fuzzer.cpp @@ -25,8 +25,9 @@ #include "updater_main.h" using namespace updater; +namespace { static constexpr int FSTAB_NAME_LENGTH = 20; - +} namespace OHOS { bool FuzzFactoryReset(const uint8_t* data, size_t size) { diff --git a/test/unittest/flashd_test/flash_host_unittest.cpp b/test/unittest/flashd_test/flash_host_unittest.cpp index d7c4e068..00c2bf3a 100755 --- a/test/unittest/flashd_test/flash_host_unittest.cpp +++ b/test/unittest/flashd_test/flash_host_unittest.cpp @@ -64,11 +64,13 @@ public: } flashHost->CommandDispatch(command, const_cast(reinterpret_cast(cmd.data())), cmd.size()); + return 0; } int TestFlashProgress(uint16_t command, const std::string &cmd, uint32_t progress) { + HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); if (task == nullptr) { @@ -112,6 +114,7 @@ public: (void)memcpy_s(cmdInfo.data(), cmdInfo.size(), &percentage, sizeof(percentage)); flashHost->CommandDispatch(CMD_UPDATER_PROGRESS, const_cast(reinterpret_cast(cmdInfo.data())), cmdInfo.size()); + return 0; } }; @@ -136,6 +139,7 @@ HWTEST_F(FLashHostUnitTest, TestFlashHostFormat, TestSize.Level1) cmdParam += " -t ext4"; EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FORMAT, cmdParam)); + cmdParam = "format "; cmdParam += TEST_PARTITION_NAME; cmdParam += " -t ext4"; diff --git a/test/unittest/package/pkg_package_unittest.cpp b/test/unittest/package/pkg_package_unittest.cpp index 2880e5cd..56578540 100755 --- a/test/unittest/package/pkg_package_unittest.cpp +++ b/test/unittest/package/pkg_package_unittest.cpp @@ -140,23 +140,13 @@ public: sizeof(CentralDirEntry) + offsetWord + offset4Words; std::vector buff(buffLen); CentralDirEntry* centralDir = (CentralDirEntry *)buff.data(); + (void)memset_s(centralDir, sizeof(CentralDirEntry), 0, sizeof(CentralDirEntry)); centralDir->signature = CENTRAL_SIGNATURE; - centralDir->versionMade = 0; - centralDir->versionNeeded = 0; - centralDir->flags = 0; centralDir->compressionMethod = PKG_COMPRESS_METHOD_ZIP; - centralDir->crc = 0; - centralDir->modifiedDate = 0; - centralDir->modifiedTime = 0; centralDir->compressedSize = UINT_MAX; centralDir->uncompressedSize = UINT_MAX; centralDir->nameSize = name.length(); centralDir->extraSize = extraSize; - centralDir->commentSize = 0; - centralDir->diskNumStart = 0; - centralDir->internalAttr = 0; - centralDir->externalAttr = 0; - centralDir->localHeaderOffset = 0; int ret = memcpy_s(buff.data() + sizeof(CentralDirEntry), name.length(), name.c_str(), name.length()); EXPECT_EQ(ret, 0); WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length(), 1); diff --git a/test/unittest/package/pkg_test.h b/test/unittest/package/pkg_test.h index e650d298..315cb420 100755 --- a/test/unittest/package/pkg_test.h +++ b/test/unittest/package/pkg_test.h @@ -70,7 +70,6 @@ protected: int32_t BuildFileDigest(uint8_t &digest, size_t size, const std::string &packagePath) { - pkgManager_ = static_cast(PkgManager::GetPackageInstance()); PkgManager::StreamPtr stream = nullptr; int32_t ret = pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); PKG_CHECK(ret == 0, return ret, "Create input stream fail %s", packagePath.c_str()); -- Gitee From 9fd2c43481b9582c519d358a67961738a4cc9d29 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Fri, 3 Dec 2021 13:53:44 +0800 Subject: [PATCH 61/94] updater: fix reviewbot Signed-off-by: xionglei6 --- test/unittest/flashd_test/flash_host_unittest.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/unittest/flashd_test/flash_host_unittest.cpp b/test/unittest/flashd_test/flash_host_unittest.cpp index 00c2bf3a..e025ad56 100755 --- a/test/unittest/flashd_test/flash_host_unittest.cpp +++ b/test/unittest/flashd_test/flash_host_unittest.cpp @@ -64,13 +64,11 @@ public: } flashHost->CommandDispatch(command, const_cast(reinterpret_cast(cmd.data())), cmd.size()); - return 0; } int TestFlashProgress(uint16_t command, const std::string &cmd, uint32_t progress) { - HTaskInfo hTaskInfo = nullptr; std::shared_ptr task = std::make_shared(); if (task == nullptr) { @@ -114,7 +112,6 @@ public: (void)memcpy_s(cmdInfo.data(), cmdInfo.size(), &percentage, sizeof(percentage)); flashHost->CommandDispatch(CMD_UPDATER_PROGRESS, const_cast(reinterpret_cast(cmdInfo.data())), cmdInfo.size()); - return 0; } }; @@ -139,7 +136,6 @@ HWTEST_F(FLashHostUnitTest, TestFlashHostFormat, TestSize.Level1) cmdParam += " -t ext4"; EXPECT_EQ(0, test.TestFlashHost(CMD_UPDATER_FORMAT, cmdParam)); - cmdParam = "format "; cmdParam += TEST_PARTITION_NAME; cmdParam += " -t ext4"; @@ -248,4 +244,4 @@ HWTEST_F(FLashHostUnitTest, TestFlashHostConfirm, TestSize.Level1) EXPECT_EQ(ret == false, 1); EXPECT_EQ(closeInput == false, 1); } -} // namespace \ No newline at end of file +} // namespace -- Gitee From 7bd51989b96a0f0ff1c8b511ccec54875274f268 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Fri, 3 Dec 2021 14:45:16 +0800 Subject: [PATCH 62/94] updater: fix reviewbot Signed-off-by: xionglei6 --- services/diffpatch/diff/blocks_diff.cpp | 4 ++-- services/flashd/host/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/diffpatch/diff/blocks_diff.cpp b/services/diffpatch/diff/blocks_diff.cpp index d579dbd9..2a68f28c 100644 --- a/services/diffpatch/diff/blocks_diff.cpp +++ b/services/diffpatch/diff/blocks_diff.cpp @@ -237,7 +237,7 @@ void BlocksDiff::ComputeLength(const BlockBuffer &newInfo, int64_t i = 0; int64_t s = 0; int64_t tmp = 0; - for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length)); ) { + for (; ((lastScan_ + i) < currentOffset_) && ((lastPos_ + i) < static_cast(oldInfo.length));) { if (oldInfo.buffer[lastPos_ + i] == newInfo.buffer[lastScan_ + i]) { s++; } @@ -413,7 +413,7 @@ void SuffixArray::Init(const BlockBuffer &oldInfo) DataType len = 0; for (h = 1; suffixArray_[0] != -(static_cast(oldInfo.length) + 1); h += h) { len = 0; - for (i = 0; i < (static_cast(oldInfo.length) + 1); ) { + for (i = 0; i < (static_cast(oldInfo.length) + 1);) { if (suffixArray_[i] < 0) { len -= suffixArray_[i]; i -= suffixArray_[i]; diff --git a/services/flashd/host/main.cpp b/services/flashd/host/main.cpp index d1dad994..a28bba7d 100755 --- a/services/flashd/host/main.cpp +++ b/services/flashd/host/main.cpp @@ -190,7 +190,7 @@ bool GetCommandlineOptions(int optArgc, const char *optArgv[]) bool needExit = false; opterr = 0; // get option parameters first - while ((ch = getopt(optArgc, (char* const *)optArgv, "hvpfms:d:t:l:")) != -1) { + while ((ch = getopt(optArgc, (char * const *)optArgv, "hvpfms:d:t:l:")) != -1) { switch (ch) { case 'h': { string usage = Hdc::TranslateCommand::Usage(); -- Gitee From 5a1b1693904c464a97337d8e5f0775762ee66e27 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Mon, 6 Dec 2021 22:20:08 +0800 Subject: [PATCH 63/94] updater: add ohflash to sdk Signed-off-by: xionglei6 --- prebuild/ohos-sdk/windows/toolchains/ohflash.exe | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 prebuild/ohos-sdk/windows/toolchains/ohflash.exe diff --git a/prebuild/ohos-sdk/windows/toolchains/ohflash.exe b/prebuild/ohos-sdk/windows/toolchains/ohflash.exe new file mode 100755 index 00000000..68350a9e --- /dev/null +++ b/prebuild/ohos-sdk/windows/toolchains/ohflash.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3fc6530c09c0db909e841a802a1eee8eaf92f2ff7ab0388b7edbeac5b8531ae +size 3297792 -- Gitee From dda6f14284b6e5773b1d1c46c3c259e0bcb78dcd Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Tue, 7 Dec 2021 09:58:57 +0800 Subject: [PATCH 64/94] updater: add oat Signed-off-by: xionglei6 --- OAT.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OAT.xml b/OAT.xml index e308ba55..6e95e429 100755 --- a/OAT.xml +++ b/OAT.xml @@ -74,7 +74,8 @@ Note:If the text contains special characters, please escape them according to th - + + -- Gitee From 7929ab86057c10aecac08fb7946cca8b8a91b525 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Tue, 7 Dec 2021 11:25:48 +0800 Subject: [PATCH 65/94] updater: fix ota Signed-off-by: xionglei6 --- OAT.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OAT.xml b/OAT.xml index 6e95e429..9aa92b4f 100755 --- a/OAT.xml +++ b/OAT.xml @@ -75,7 +75,7 @@ Note:If the text contains special characters, please escape them according to th - + -- Gitee From fd7ea4aec5513f69acbf962d747ed84c5f5ba04d Mon Sep 17 00:00:00 2001 From: northking-super Date: Thu, 16 Dec 2021 09:29:49 +0000 Subject: [PATCH 66/94] depend root modify:device structure change Signed-off-by: northking-super --- services/BUILD.gn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 services/BUILD.gn diff --git a/services/BUILD.gn b/services/BUILD.gn old mode 100644 new mode 100755 index 945f511d..da6e26e4 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -35,14 +35,14 @@ ohos_prebuilt_etc("updater_init_usb_configfs.cfg") { ohos_prebuilt_etc("signing_cert.crt") { source = - "//device/hisilicon/hi3516dv300/build/updater_config/signing_cert.crt" + "//device/board/hisilicon/hispark_taurus/linux/updater/config/signing_cert.crt" module_install_dir = "certificate" install_images = [ "updater" ] part_name = "updater" } ohos_prebuilt_etc("fstab.updater") { - source = "//device/hisilicon/hi3516dv300/build/vendor/etc/fstab.updater" + source = "//device/board/hisilicon/hispark_taurus/linux/updater/config/fstab.updater" install_images = [ "updater" ] part_name = "updater" } -- Gitee From 591ae57fe150bccd32425f4b0dffa3f2e0591520 Mon Sep 17 00:00:00 2001 From: handyohos Date: Thu, 23 Dec 2021 14:44:11 +0800 Subject: [PATCH 67/94] fix: add libbegetutil for init component. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对init部件的依赖统一到libbegetutil模块。 fix #I4NSE7 Signed-off-by: handyohos Change-Id: I5fd4e299a97b29505887c0ef4c00c8ca11eae2fb --- interfaces/kits/misc_info/BUILD.gn | 3 ++- services/BUILD.gn | 3 ++- services/applypatch/BUILD.gn | 2 +- services/flashd/BUILD.gn | 16 +++++----------- services/fs_manager/BUILD.gn | 4 ++-- services/updater_binary/BUILD.gn | 3 ++- test/unittest/BUILD.gn | 9 +++++---- utils/BUILD.gn | 4 ++-- 8 files changed, 21 insertions(+), 23 deletions(-) diff --git a/interfaces/kits/misc_info/BUILD.gn b/interfaces/kits/misc_info/BUILD.gn index 7bcc7112..a184f973 100755 --- a/interfaces/kits/misc_info/BUILD.gn +++ b/interfaces/kits/misc_info/BUILD.gn @@ -21,7 +21,6 @@ ohos_static_library("libmiscinfo") { "//base/update/updater/services/include", "//base/update/updater/utils/include", "//third_party/bounds_checking_function/include", - "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ @@ -29,4 +28,6 @@ ohos_static_library("libmiscinfo") { "//base/update/updater/services/log:libupdaterlog", "//third_party/bounds_checking_function:libsec_static", ] + + external_deps = [ "init:libbegetutil" ] } diff --git a/services/BUILD.gn b/services/BUILD.gn index 945f511d..2f52fb6a 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -87,7 +87,6 @@ ohos_executable("updater") { "//base/update/updater/services", "//base/update/updater/services/ui", "//base/update/updater/services/include", - "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ @@ -109,6 +108,8 @@ ohos_executable("updater") { "//third_party/openssl:ssl_source", "//third_party/zlib:libz", ] + + external_deps = [ "init:libbegetutil" ] install_images = [ "updater" ] install_enable = true part_name = "updater" diff --git a/services/applypatch/BUILD.gn b/services/applypatch/BUILD.gn index 43765bfd..f758e3cc 100644 --- a/services/applypatch/BUILD.gn +++ b/services/applypatch/BUILD.gn @@ -39,7 +39,6 @@ ohos_static_library("libapplypatch") { "//base/update/updater/services/include/package", "//base/update/updater/services/include/log", "//third_party/bounds_checking_function/include", - "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ @@ -48,4 +47,5 @@ ohos_static_library("libapplypatch") { "//third_party/bounds_checking_function:libsec_static", "//third_party/bzip2:libbz2", ] + external_deps = [ "init:libbegetutil" ] } diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn index ab998573..c505c593 100755 --- a/services/flashd/BUILD.gn +++ b/services/flashd/BUILD.gn @@ -66,9 +66,9 @@ ohos_source_set("flashd_deamon") { ] if (use_musl) { - deps += [ - "//base/startup/init_lite/interfaces/innerkits/reboot:libreboot_static", - "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", + external_deps = [ + "init:libbegetutil", + "startup_l2:syspara", ] } @@ -84,13 +84,6 @@ ohos_source_set("flashd_deamon") { "//third_party/openssl/include", "//third_party/libuv", ] - - if (use_musl) { - include_dirs += [ - "//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include", - "//base/startup/init_lite/interfaces/innerkits/include", - ] - } } ohos_static_library("libflashd") { @@ -148,9 +141,10 @@ ohos_static_library("libflashd") { "//utils/native/base/include", "//third_party/lz4/lib", "//third_party/libuv", - "//base/startup/init_lite/interfaces/innerkits/include", ] + external_deps = [ "init:libbegetutil" ] + part_name = "updater" } diff --git a/services/fs_manager/BUILD.gn b/services/fs_manager/BUILD.gn index 93aad545..911b235e 100644 --- a/services/fs_manager/BUILD.gn +++ b/services/fs_manager/BUILD.gn @@ -26,12 +26,12 @@ ohos_static_library("libfsmanager") { "//base/update/updater/interfaces/kits/include", "//base/update/updater/utils/include", "//third_party/bounds_checking_function/include", - "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ - "//base/startup/init_lite/interfaces/innerkits/fs_manager:libfsmanager_static", "//base/update/updater/utils:libutils", "//third_party/bounds_checking_function:libsec_static", ] + + external_deps = [ "init:libbegetutil" ] } diff --git a/services/updater_binary/BUILD.gn b/services/updater_binary/BUILD.gn index 6c2a2237..a6acef58 100644 --- a/services/updater_binary/BUILD.gn +++ b/services/updater_binary/BUILD.gn @@ -27,7 +27,6 @@ config("updater_config") { "//third_party/openssl/include", "//third_party/bounds_checking_function/include", "//drivers/hdf/frameworks/include/utils", - "//base/startup/init_lite/interfaces/innerkits/include", ] } @@ -59,6 +58,8 @@ ohos_executable("updater_binary") { "//third_party/zlib:libz", ] + external_deps = [ "init:libbegetutil" ] + install_enable = true part_name = "updater" } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 5ad65418..6d7a9fc2 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -144,7 +144,6 @@ ohos_unittest("updater_unittest") { ] include_dirs = [ - "//base/startup/init_lite/interfaces/innerkits/include", "//base/update/updater/interfaces/kits/include/", "//base/update/updater/interfaces/kits/include/package", "//base/update/updater/services/include/", @@ -200,11 +199,8 @@ ohos_unittest("updater_unittest") { "//drivers/peripheral/input/hal/include", "//drivers/peripheral/input/interfaces/include", "//third_party/bounds_checking_function/include", - "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ - "//base/startup/init_lite/interfaces/innerkits/fs_manager:libfsmanager_static", - "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", "//base/update/updater/interfaces/kits/misc_info:libmiscinfo", "//base/update/updater/services/applypatch:libapplypatch", "//base/update/updater/services/diffpatch/diff:libdiff", @@ -232,6 +228,11 @@ ohos_unittest("updater_unittest") { "//base/update/updater/test/unittest:test_update_binary_abnormal", ] + external_deps = [ + "init:libbegetutil", + "startup_l2:syspara", + ] + cflags_cc = [ "-fexceptions" ] defines = [ diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 2adba505..f1cc048f 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -21,10 +21,10 @@ ohos_static_library("libutils") { "//base/update/updater/interfaces/kits/include/", "//base/update/updater/services/include/", "//third_party/bounds_checking_function/include", - "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ "//third_party/bounds_checking_function:libsec_static" ] + external_deps = [ "init:libbegetutil" ] } ohos_executable("updater_reboot") { @@ -54,7 +54,6 @@ ohos_executable("write_updater") { "//base/update/updater/interfaces/kits/include/", "//base/update/updater/services/include/", "//third_party/bounds_checking_function/include", - "//base/startup/init_lite/interfaces/innerkits/include", ] deps = [ @@ -64,6 +63,7 @@ ohos_executable("write_updater") { "//base/update/updater/utils:libutils", "//third_party/bounds_checking_function:libsec_static", ] + external_deps = [ "init:libbegetutil" ] install_enable = true part_name = "updater" -- Gitee From e0f65b744884f4e2271d80476e36664bbf0efb39 Mon Sep 17 00:00:00 2001 From: northking-super Date: Sat, 25 Dec 2021 08:54:31 +0000 Subject: [PATCH 68/94] format modify Signed-off-by: northking-super --- services/BUILD.gn | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/services/BUILD.gn b/services/BUILD.gn index da6e26e4..6f00a371 100755 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -34,8 +34,7 @@ ohos_prebuilt_etc("updater_init_usb_configfs.cfg") { } ohos_prebuilt_etc("signing_cert.crt") { - source = - "//device/board/hisilicon/hispark_taurus/linux/updater/config/signing_cert.crt" + source = "//device/board/hisilicon/hispark_taurus/linux/updater/config/signing_cert.crt" module_install_dir = "certificate" install_images = [ "updater" ] part_name = "updater" -- Gitee From 6e1a3e75111895bc5d7801c374c676a83a8ea53d Mon Sep 17 00:00:00 2001 From: handyohos Date: Sun, 26 Dec 2021 22:01:23 +0800 Subject: [PATCH 69/94] feat: Compile jsapi module only if support_jsapi is true. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 仅在support_jsapi为true时才编译jsapi模块 Signed-off-by: handyohos Change-Id: I6840a1d7a482d0eedbd1ce814df68e963531f4a4 #I4O4N6 --- ohos.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ohos.build b/ohos.build index 010ef856..3dadad4f 100644 --- a/ohos.build +++ b/ohos.build @@ -21,7 +21,7 @@ "//base/update/updater/interfaces/kits/misc_info:libmiscinfo", "//base/update/updater/interfaces/kits/packages:libpackageExt", "//base/update/updater/interfaces/kits/updaterkits:libupdaterkits", - "//base/update/updateservice/client:update", + "//base/update/updateservice:update_client_jsapi", "//base/update/updateservice/engine:updateservice", "//base/update/updateservice/engine:updater_sa.rc", "//base/update/updateservice/engine/sa_profile:updater_sa_profile", -- Gitee From 07181c9948697519d06da159190699514177dd99 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Sat, 15 Jan 2022 11:34:55 +0800 Subject: [PATCH 70/94] updater: test Signed-off-by: xionglei6 --- services/main.cpp | 2 -- services/updater_binary/main.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/services/main.cpp b/services/main.cpp index d6a5e6da..6f5d5fe9 100644 --- a/services/main.cpp +++ b/services/main.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ #include "fs_manager/mount.h" -#include "fs_manager/fs_manager_log.h" #include "flashd/flashd.h" #include "log/log.h" #include "misc_info/misc_info.h" @@ -33,7 +32,6 @@ int main(int argc, char **argv) InitUpdaterLogger((mode == BOOT_FLASHD) ? "FLASHD" : "UPDATER", TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH); SetLogLevel(INFO); - FsManagerLogInit(LOG_TO_FILE, TMP_LOG.c_str()); LoadFstab(); STAGE(UPDATE_STAGE_OUT) << "Start " << ((mode == BOOT_FLASHD) ? "flashd" : "updater"); if (mode == BOOT_FLASHD) { diff --git a/services/updater_binary/main.cpp b/services/updater_binary/main.cpp index 10ccdd89..68aaaff5 100644 --- a/services/updater_binary/main.cpp +++ b/services/updater_binary/main.cpp @@ -18,7 +18,6 @@ #include #include #include "fs_manager/mount.h" -#include "fs_manager/fs_manager_log.h" #include "log.h" #include "updater/updater_const.h" #include "update_processor.h" @@ -33,7 +32,6 @@ int main(int argc, char **argv) LOG(ERROR) << "Invalid arguments."; return EXIT_INVALID_ARGS; } - FsManagerLogInit(LOG_TO_FILE, TMP_LOG.c_str()); bool retry = false; int pipeFd = static_cast(std::strtol(argv[1], nullptr, DECIMAL)); if (argc >= BINARY_MAX_ARGS && strcmp(argv[BINARY_SECOND_ARG], "retry") == 0) { -- Gitee From 82b75fc72fb235472a0a1d653c7b5d8a2d25c8b2 Mon Sep 17 00:00:00 2001 From: fengjiahui4 Date: Tue, 25 Jan 2022 12:42:46 +0800 Subject: [PATCH 71/94] =?UTF-8?q?=E5=88=A0=E9=99=A4ohos.build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fengjiahui4 --- bundle.json | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ohos.build | 40 ------------------ 2 files changed, 120 insertions(+), 40 deletions(-) create mode 100644 bundle.json delete mode 100644 ohos.build diff --git a/bundle.json b/bundle.json new file mode 100644 index 00000000..5219151d --- /dev/null +++ b/bundle.json @@ -0,0 +1,120 @@ +{ + "name": "@ohos/update_updater", + "version": "3.1", + "description": "升级包安装组件运行在recovery分区,其功能主要包括读取misc分区信息获取升级包状态,对升级包进行校验,确保升级包合法有效;然后从升级包中解析出升级的可执行程序,创建子进程并启动升级程序。具体升级的动作由升级脚本控制。", + "homePage": "https://gitee.com/openharmony", + "license": "Apache License 2.0", + "repository": "https://gitee.com/openharmony/update_updater", + "domain": "os", + "language": "", + "publishAs": "code-segment", + "private": false, + "scripts": {}, + "tags": [ + "base" + ], + "keywords": [ + "update", + "updater" + ], + "envs": {}, + "dirs": {}, + "author": { + "name": "", + "email": "", + "url": "" + }, + "contributors": [ + { + "name": "", + "email": "", + "url": "" + } + ], + "segment": { + "destPath": "base/update/updater" + }, + "component": { + "name": "updater", + "subsystem": "updater", + "syscap": [], + "features": [], + "adapted_system_type": [ "standard" ], + "rom": "", + "ram": "", + "deps": { + "components": [ + "startup_init_lite", + "startup_syspara_lite", + "developtools_hdc_standard", + "utils_native", + "drivers_peripheral" + ], + "third_party": [ + "third_party_bounds_checking_function", + "third_party_bzip2", + "third_party_libdrm", + "third_party_lz4", + "third_party_openssl", + "third_party_libusb", + "third_party_zlib", + "third_party_libuv", + "third_party_cJSON", + "third_party_libpng" + ] + }, + "build": { + "sub_component": [ + "//base/update/updater/resources:updater_resources", + "//base/update/updater/services:updater_etc", + "//base/update/updater/services/package:libupdaterpackage", + "//base/update/updater/services/script:libupdaterscript", + "//base/update/updater/services/log:libupdaterlog", + "//base/update/updater/services/updater_binary:updater_binary", + "//base/update/updater/services:updater", + "//base/update/updater/services/applypatch:libapplypatch", + "//base/update/updater/services/fs_manager:libfsmanager", + "//base/update/updater/services/flashd:updater_flashd", + "//base/update/updater/utils:libutils", + "//base/update/updater/utils:updater_reboot", + "//base/update/updater/utils:write_updater", + "//base/update/updater/services/diffpatch/patch:libpatch", + "//base/update/updater/services/diffpatch/diff:libdiff", + "//base/update/updater/services/ui:libui" + ], + "inner_kits": [ + { + "name": "//base/update/updater/interfaces/kits/misc_info:libmiscinfo", + "header": { + "header_files": [ + "misc_info/misc_info.h" + ], + "header_base": "//base/update/updater/interfaces/kits/include" + } + }, + { + "name": "//base/update/updater/interfaces/kits/packages:libpackageExt", + "header": { + "header_files": [ + "package/package.h" + ], + "header_base": "//base/update/updater/interfaces/kits/include" + } + }, + { + "name": "//base/update/updater/interfaces/kits/updaterkits:libupdaterkits", + "header": { + "header_files": [ + "updaterkits/updaterkits.h" + ], + "header_base": "//base/update/updater/interfaces/kits/include" + } + } + ], + "test": [ + "//base/update/updater:unittest" + ] + } + } +} + diff --git a/ohos.build b/ohos.build deleted file mode 100644 index 3dadad4f..00000000 --- a/ohos.build +++ /dev/null @@ -1,40 +0,0 @@ -{ - "subsystem": "updater", - "parts": { - "updater": { - "module_list": [ - "//base/update/updater/resources:updater_resources", - "//base/update/updater/services:updater_etc", - "//base/update/updater/services/package:libupdaterpackage", - "//base/update/updater/services/script:libupdaterscript", - "//base/update/updater/services/log:libupdaterlog", - "//base/update/updater/services/updater_binary:updater_binary", - "//base/update/updater/services:updater", - "//base/update/updater/services/applypatch:libapplypatch", - "//base/update/updater/services/fs_manager:libfsmanager", - "//base/update/updater/services/flashd:updater_flashd", - "//base/update/updater/utils:libutils", - "//base/update/updater/utils:updater_reboot", - "//base/update/updater/utils:write_updater", - "//base/update/updater/services/diffpatch/patch:libpatch", - "//base/update/updater/services/diffpatch/diff:libdiff", - "//base/update/updater/interfaces/kits/misc_info:libmiscinfo", - "//base/update/updater/interfaces/kits/packages:libpackageExt", - "//base/update/updater/interfaces/kits/updaterkits:libupdaterkits", - "//base/update/updateservice:update_client_jsapi", - "//base/update/updateservice/engine:updateservice", - "//base/update/updateservice/engine:updater_sa.rc", - "//base/update/updateservice/engine/sa_profile:updater_sa_profile", - "//base/update/updateservice/interfaces/innerkits/engine:updateservicekits", - "//base/update/updater/services/ui:libui", - "//third_party/libdrm:libdrm", - "//third_party/e2fsprogs:e2fsprogs" - ], - "test_list": [ - "//base/update/updater:unittest" - ] - } - } -} - - -- Gitee From d860bb6be6565eff764516f1dd8af833a2940005 Mon Sep 17 00:00:00 2001 From: xionglei6 Date: Wed, 16 Feb 2022 17:22:05 +0800 Subject: [PATCH 72/94] modify: cfg adapt ueventd ondemand Signed-off-by: xionglei6 --- services/etc/init.cfg | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/services/etc/init.cfg b/services/etc/init.cfg index a1f12f5d..c69e192a 100755 --- a/services/etc/init.cfg +++ b/services/etc/init.cfg @@ -77,7 +77,24 @@ "gid" : 2000, "once" : 0, "importance" : 0, - "caps" : [0, 1] + "caps" : [0, 1], + "socket" : [{ + "name" : "ueventd", + "family" : "AF_NETLINK", + "type" : "SOCK_DGRAM", + "protocol" : "NETLINK_KOBJECT_UEVENT", + "permissions" : "0660", + "uid" : "0", + "gid" : "2000", + "option" : [ + "SOCKET_OPTION_PASSCRED", + "SOCKET_OPTION_RCVBUFFORCE", + "SOCK_CLOEXEC", + "SOCK_NONBLOCK" + ] + }], + "critical" : [ 0, 15, 5], + "ondemand" : true } ] } -- Gitee From 27b5e00f76f72e576edccfd19a4587a8911e52ca Mon Sep 17 00:00:00 2001 From: chenzihan Date: Thu, 24 Feb 2022 17:47:34 +0800 Subject: [PATCH 73/94] Signed-off-by: chenzihan fix doc --- README.md | 12 ++++++------ README_zh.md | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 7953eb83..cdf37172 100755 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## Introduction -The updater runs in the recovery partition. It reads the misc partition information to obtain the update package status and verifies the update package to ensure that the update package is valid. Then, the updater parses the executable program from the update package, creates a subprocess, and starts the update program. After that, update operations will be automatically implemented by the update script. +The updater runs in the updater partition. It reads the misc partition information to obtain the update package status and verifies the update package to ensure that the update package is valid. Then, the updater parses the executable program from the update package, creates a subprocess, and starts the update program. After that, update operations will be automatically implemented by the update script. ## Directory Structure @@ -37,11 +37,11 @@ base/update/updater/ ### Usage Guidelines -The updater runs in the recovery partition. To ensure proper functioning of the updater, perform the following operations: +The updater runs in the updater partition. To ensure proper functioning of the updater, perform the following operations: -1. Create a recovery partition. +1. Create a updater partition. -The recovery partition is independent of other partitions. It is recommended that the size of the recovery partition be greater than or equal to 20 MB. The recovery partition image is an ext4 file system. Ensure that the **config** option of the ext4 file system in the system kernel is enabled. +The updater partition is independent of other partitions. It is recommended that the size of the updater partition be greater than or equal to 20 MB. The updater partition image is an ext4 file system. Ensure that the **config** option of the ext4 file system in the system kernel is enabled. 2. Create the misc partition. @@ -53,7 +53,7 @@ During the update process, the updater needs to operate the partitions through t 4. Start the updater. -The init process in the recovery partition has an independent configuration file named **init.cfg**. The startup configuration of the updater is stored in this file. +The init process in the updater partition has an independent configuration file named **init.cfg**. The startup configuration of the updater is stored in this file. 5. Compile the updater. @@ -78,7 +78,7 @@ For example, to add the updater for Hi3516D V300, add the following code to the "updater:updater":{}, ``` -6. Compile the recovery partition image. +6. Compile the updater partition image. Add the compilation configuration to the **build\_updater\_image.sh** script, which is stored in the **build** repository and called by the OpenHarmony compilation system. diff --git a/README_zh.md b/README_zh.md index 62c79a58..e8900d27 100755 --- a/README_zh.md +++ b/README_zh.md @@ -9,7 +9,7 @@ ## 简介 -升级包安装组件运行在recovery分区,其功能主要包括读取misc分区信息获取升级包状态,对升级包进行校验,确保升级包合法有效;然后从升级包中解析出升级的可执行程序,创建子进程并启动升级程序。具体升级的动作由升级脚本控制。 +升级包安装组件运行在updater分区,其功能主要包括读取misc分区信息获取升级包状态,对升级包进行校验,确保升级包合法有效;然后从升级包中解析出升级的可执行程序,创建子进程并启动升级程序。具体升级的动作由升级脚本控制。 ## 目录 @@ -37,11 +37,11 @@ base/update/updater/ ### 使用说明 -升级包安装组件运行在recovery分区里,需要如下的操作 +升级包安装组件运行在updater分区里,需要如下的操作 -1、创建recovery分区 +1、创建updater分区 -recovery是一个独立的分区,分区大小建议不小于20MB。recovery分区镜像是ext4 格式文件系统。确保系统内核ext4 文件系统的config 是打开状态。 +updater是一个独立的分区,分区大小建议不小于20MB。updater分区镜像是ext4 格式文件系统。确保系统内核ext4 文件系统的config 是打开状态。 2、创建misc分区 @@ -53,7 +53,7 @@ misc 分区中存储了升级子系统在升级过程中需要的元数据\(meta 4、升级包安装组件启动 -recovery分区的init 进程有单独的配置文件 init.cfg,升级包安装进程启动配置在该文件中。 +updater分区的init 进程有单独的配置文件 init.cfg,升级包安装进程启动配置在该文件中。 5、升级包安装组件编译 @@ -78,7 +78,7 @@ b、 产品中添加需要编译的组件 "updater:updater":{}, ``` -6、recovery分区镜像编译 +6、updater分区镜像编译 编译配置在build仓下,build\_updater\_image.sh 脚本中,该脚本由OHOS 编译系统调用。 -- Gitee From 3d51173095a03632d1b63fe0de8ab039c5993589 Mon Sep 17 00:00:00 2001 From: chenzihan Date: Fri, 25 Feb 2022 17:45:59 +0800 Subject: [PATCH 74/94] Signed-off-by: chenzihan fix:update_updater\services\package\pkg_package\pkg_zipfile.cpp --- services/package/pkg_package/pkg_zipfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/package/pkg_package/pkg_zipfile.cpp b/services/package/pkg_package/pkg_zipfile.cpp index 5ea2eb6b..27dcc288 100644 --- a/services/package/pkg_package/pkg_zipfile.cpp +++ b/services/package/pkg_package/pkg_zipfile.cpp @@ -109,7 +109,7 @@ int32_t ZipPkgFile::LoadPackage(std::vector &fileNames, const PkgBu (endDir.startDiskOfCentralDir != 0) #ifndef UPDATER_UT || (endDir.offset >= fileLen) || (endDir.totalEntriesInThisDisk != endDir.totalEntries) || - (endDir.commentLen = 0) || ((endDir.offset + endDir.sizeOfCentralDir + endDirLen) > fileLen) + (endDir.commentLen == 0) || ((endDir.offset + endDir.sizeOfCentralDir + endDirLen) > fileLen) #endif ) { PKG_LOGE("end dir format error %s", pkgStream_->GetFileName().c_str()); -- Gitee From a7f626e8b3f16358d3c861b51511cc795dd9fda8 Mon Sep 17 00:00:00 2001 From: yudechen Date: Wed, 2 Mar 2022 11:15:57 +0800 Subject: [PATCH 75/94] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=8C=87=E5=AE=9A=E9=83=A8=E4=BB=B6=E5=92=8C?= =?UTF-8?q?=E5=AD=90=E7=B3=BB=E7=BB=9F=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit re #I4VWKX Signed-off-by: yudechen Change-Id: If43cff580d3010b6d3c3aaa09b9adc8020e41624 --- interfaces/kits/misc_info/BUILD.gn | 3 +++ interfaces/kits/packages/BUILD.gn | 2 ++ interfaces/kits/updaterkits/BUILD.gn | 3 +++ services/applypatch/BUILD.gn | 2 ++ services/diffpatch/diff/BUILD.gn | 3 +++ services/diffpatch/patch/BUILD.gn | 2 ++ services/fs_manager/BUILD.gn | 2 ++ services/log/BUILD.gn | 2 ++ services/package/BUILD.gn | 2 ++ services/script/BUILD.gn | 3 +++ services/ui/BUILD.gn | 3 +++ utils/BUILD.gn | 3 +++ 12 files changed, 30 insertions(+) diff --git a/interfaces/kits/misc_info/BUILD.gn b/interfaces/kits/misc_info/BUILD.gn index a184f973..37a3aedc 100755 --- a/interfaces/kits/misc_info/BUILD.gn +++ b/interfaces/kits/misc_info/BUILD.gn @@ -30,4 +30,7 @@ ohos_static_library("libmiscinfo") { ] external_deps = [ "init:libbegetutil" ] + + subsystem_name = "updater" + part_name = "updater" } diff --git a/interfaces/kits/packages/BUILD.gn b/interfaces/kits/packages/BUILD.gn index aad7ffe4..9d8efcd3 100755 --- a/interfaces/kits/packages/BUILD.gn +++ b/interfaces/kits/packages/BUILD.gn @@ -33,4 +33,6 @@ ohos_static_library("libpackageExt") { "//third_party/openssl:ssl_source", "//third_party/zlib:libz", ] + subsystem_name = "updater" + part_name = "updater" } diff --git a/interfaces/kits/updaterkits/BUILD.gn b/interfaces/kits/updaterkits/BUILD.gn index 6cd54b64..fd59e521 100755 --- a/interfaces/kits/updaterkits/BUILD.gn +++ b/interfaces/kits/updaterkits/BUILD.gn @@ -29,4 +29,7 @@ ohos_static_library("libupdaterkits") { "//base/update/updater/utils:libutils", "//third_party/bounds_checking_function:libsec_static", ] + + subsystem_name = "updater" + part_name = "updater" } diff --git a/services/applypatch/BUILD.gn b/services/applypatch/BUILD.gn index f758e3cc..ec459547 100644 --- a/services/applypatch/BUILD.gn +++ b/services/applypatch/BUILD.gn @@ -48,4 +48,6 @@ ohos_static_library("libapplypatch") { "//third_party/bzip2:libbz2", ] external_deps = [ "init:libbegetutil" ] + subsystem_name = "updater" + part_name = "updater" } diff --git a/services/diffpatch/diff/BUILD.gn b/services/diffpatch/diff/BUILD.gn index e9e37cde..c980ca09 100644 --- a/services/diffpatch/diff/BUILD.gn +++ b/services/diffpatch/diff/BUILD.gn @@ -46,4 +46,7 @@ ohos_static_library("libdiff") { "//third_party/bzip2:libbz2", ] configs = [ ":diff_config" ] + + subsystem_name = "updater" + part_name = "updater" } diff --git a/services/diffpatch/patch/BUILD.gn b/services/diffpatch/patch/BUILD.gn index 0a28158a..912a88b2 100644 --- a/services/diffpatch/patch/BUILD.gn +++ b/services/diffpatch/patch/BUILD.gn @@ -52,4 +52,6 @@ ohos_static_library("libpatch") { ] configs = [ ":patch_config" ] + subsystem_name = "updater" + part_name = "updater" } diff --git a/services/fs_manager/BUILD.gn b/services/fs_manager/BUILD.gn index 911b235e..604e9096 100644 --- a/services/fs_manager/BUILD.gn +++ b/services/fs_manager/BUILD.gn @@ -34,4 +34,6 @@ ohos_static_library("libfsmanager") { ] external_deps = [ "init:libbegetutil" ] + subsystem_name = "updater" + part_name = "updater" } diff --git a/services/log/BUILD.gn b/services/log/BUILD.gn index a063f69d..f4d07de8 100644 --- a/services/log/BUILD.gn +++ b/services/log/BUILD.gn @@ -23,4 +23,6 @@ ohos_static_library("libupdaterlog") { ] deps = [ "//third_party/bounds_checking_function:libsec_static" ] + subsystem_name = "updater" + part_name = "updater" } diff --git a/services/package/BUILD.gn b/services/package/BUILD.gn index d947f2f8..142054f0 100644 --- a/services/package/BUILD.gn +++ b/services/package/BUILD.gn @@ -58,4 +58,6 @@ ohos_static_library("libupdaterpackage") { deps = [ "//third_party/bounds_checking_function:libsec_static" ] configs = [ ":package_config" ] + subsystem_name = "updater" + part_name = "updater" } diff --git a/services/script/BUILD.gn b/services/script/BUILD.gn index 641fe9ea..41ddffaf 100644 --- a/services/script/BUILD.gn +++ b/services/script/BUILD.gn @@ -66,4 +66,7 @@ ohos_static_library("libupdaterscript") { "//third_party/bounds_checking_function:libsec_static", "//utils/native/base:utils", ] + + subsystem_name = "updater" + part_name = "updater" } diff --git a/services/ui/BUILD.gn b/services/ui/BUILD.gn index edab2abd..760019c0 100644 --- a/services/ui/BUILD.gn +++ b/services/ui/BUILD.gn @@ -55,4 +55,7 @@ ohos_static_library("libui") { "//third_party/libdrm:libdrm", "//third_party/libpng:libpng", ] + + subsystem_name = "updater" + part_name = "updater" } diff --git a/utils/BUILD.gn b/utils/BUILD.gn index f1cc048f..7a945c0c 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -25,6 +25,9 @@ ohos_static_library("libutils") { deps = [ "//third_party/bounds_checking_function:libsec_static" ] external_deps = [ "init:libbegetutil" ] + + subsystem_name = "updater" + part_name = "updater" } ohos_executable("updater_reboot") { -- Gitee From fd1265ed0f2c411b0d509a2f37877e5ad636d82f Mon Sep 17 00:00:00 2001 From: chenzihan Date: Fri, 25 Feb 2022 17:45:59 +0800 Subject: [PATCH 76/94] Signed-off-by: chenzihan fix:update_updater\services\package\pkg_package\pkg_zipfile.cpp --- services/package/pkg_package/pkg_zipfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/package/pkg_package/pkg_zipfile.cpp b/services/package/pkg_package/pkg_zipfile.cpp index 5ea2eb6b..df5626c4 100644 --- a/services/package/pkg_package/pkg_zipfile.cpp +++ b/services/package/pkg_package/pkg_zipfile.cpp @@ -109,7 +109,7 @@ int32_t ZipPkgFile::LoadPackage(std::vector &fileNames, const PkgBu (endDir.startDiskOfCentralDir != 0) #ifndef UPDATER_UT || (endDir.offset >= fileLen) || (endDir.totalEntriesInThisDisk != endDir.totalEntries) || - (endDir.commentLen = 0) || ((endDir.offset + endDir.sizeOfCentralDir + endDirLen) > fileLen) + ((endDir.offset + endDir.sizeOfCentralDir + endDirLen) > fileLen) #endif ) { PKG_LOGE("end dir format error %s", pkgStream_->GetFileName().c_str()); -- Gitee From 04812419f825b49d804a87dcde2191c7d72446cb Mon Sep 17 00:00:00 2001 From: yudechen Date: Mon, 7 Mar 2022 15:36:37 +0800 Subject: [PATCH 77/94] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=8C=87=E5=AE=9A=E9=83=A8=E4=BB=B6=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yudechen Change-Id: Ib5ddbfde21e0b171af5ab5e6de0af71013546e30 --- services/flashd/BUILD.gn | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn index c505c593..8f37f8a1 100755 --- a/services/flashd/BUILD.gn +++ b/services/flashd/BUILD.gn @@ -84,6 +84,9 @@ ohos_source_set("flashd_deamon") { "//third_party/openssl/include", "//third_party/libuv", ] + + subsystem_name = "updater" + part_name = "updater" } ohos_static_library("libflashd") { -- Gitee From bdc9712c390d1e38c0498931d6e9c18afe90b047 Mon Sep 17 00:00:00 2001 From: hughes Date: Fri, 11 Mar 2022 08:25:49 +0000 Subject: [PATCH 78/94] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=A9=BA=E6=8C=87?= =?UTF-8?q?=E9=92=88=E6=BC=8F=E6=B4=9E=20Signed-off-by:hughes802=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/package/pkg_package/pkg_upgradefile.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/services/package/pkg_package/pkg_upgradefile.cpp b/services/package/pkg_package/pkg_upgradefile.cpp index 85d4e1e0..72e466ea 100644 --- a/services/package/pkg_package/pkg_upgradefile.cpp +++ b/services/package/pkg_package/pkg_upgradefile.cpp @@ -326,6 +326,11 @@ int32_t UpgradePkgFile::ReadUpgradePkgHeader(const PkgBuffer &buffer, size_t &re PkgFile::ConvertBufferToString(pkgInfo_.productUpdateId, {header->productUpdateId, sizeof(header->productUpdateId)}); + algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(pkgInfo_.pkgInfo.digestMethod); + PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, + "Invalid file %s", pkgStream_->GetFileName().c_str()); + algorithm->Init(); + if (currLen + tlv.length >= readLen) { // Extra TLV information, read it. realLen = currLen + tlv.length; algorithm->Update(buffer, realLen); @@ -348,10 +353,6 @@ int32_t UpgradePkgFile::ReadUpgradePkgHeader(const PkgBuffer &buffer, size_t &re realLen += currLen; // Parser header to get compressional algorithm - algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(pkgInfo_.pkgInfo.digestMethod); - PKG_CHECK(algorithm != nullptr, return PKG_NOT_EXIST_ALGORITHM, - "Invalid file %s", pkgStream_->GetFileName().c_str()); - algorithm->Init(); algorithm->Update(buffer, currLen); // Generate digest return PKG_SUCCESS; } -- Gitee From 6e9a114757c8d5c376f5e34074e7d8319cc9c698 Mon Sep 17 00:00:00 2001 From: zhoushilin Date: Fri, 18 Mar 2022 10:10:27 +0800 Subject: [PATCH 79/94] change securec path Signed-off-by: zhoushilin --- services/flashd/BUILD.gn | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/services/flashd/BUILD.gn b/services/flashd/BUILD.gn index 8f37f8a1..f38b79b3 100755 --- a/services/flashd/BUILD.gn +++ b/services/flashd/BUILD.gn @@ -79,7 +79,7 @@ ohos_source_set("flashd_deamon") { "//base/update/updater/services/flashd/daemon", "//base/update/updater/services/flashd/common", "//base/update/updater/services/flashd/host", - "//utils/native/base/include", + "//third_party/bounds_checking_function/include", "//third_party/lz4/lib", "//third_party/openssl/include", "//third_party/libuv", @@ -141,7 +141,6 @@ ohos_static_library("libflashd") { "//third_party/bounds_checking_function/include", "//third_party/cJSON", "//third_party/openssl/include", - "//utils/native/base/include", "//third_party/lz4/lib", "//third_party/libuv", ] @@ -182,11 +181,11 @@ ohos_executable("ohflash") { sources += common_sources deps = [ + "//third_party/bounds_checking_function:libsec_static", "//third_party/libusb:libusb", "//third_party/libuv:uv_static", "//third_party/lz4:liblz4_static", "//third_party/openssl:libcrypto_static", - "//utils/native/base:utilsecurec", ] deps += [ "//third_party/libusb:libusb" ] @@ -196,7 +195,7 @@ ohos_executable("ohflash") { "${HDC_PATH}/host", "${FLASHD_PATH}/common", "${HDC_PATH}/common", - "//utils/native/base/include", + "//third_party/bounds_checking_function/include", "//third_party/lz4/lib", "//third_party/openssl/include", "//third_party/libuv", -- Gitee From de56a18f73ffa68b53aecc7efb05a1ac3e917e01 Mon Sep 17 00:00:00 2001 From: hughes Date: Wed, 23 Mar 2022 07:43:35 +0000 Subject: [PATCH 80/94] Signed-off-by: hughes802 --- bundle.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bundle.json b/bundle.json index 5219151d..42a5a0fd 100644 --- a/bundle.json +++ b/bundle.json @@ -111,9 +111,7 @@ } } ], - "test": [ - "//base/update/updater:unittest" - ] + "test": [] } } } -- Gitee From 0655a874308b241a473cb9e2d5c57a35c66fb8dc Mon Sep 17 00:00:00 2001 From: chenzihan Date: Thu, 24 Mar 2022 19:10:21 +0800 Subject: [PATCH 81/94] Signed-off-by: chenzihan fix:codex warning fix --- services/applypatch/transfer_manager.cpp | 2 -- services/flashd/host/translate.cpp | 2 -- .../package/pkg_algorithm/pkg_algo_digest.cpp | 1 - services/package/pkg_package/pkg_upgradefile.cpp | 16 ++++++++-------- services/ui/text_label.cpp | 1 - services/updater_binary/update_image_block.cpp | 12 +++++++----- services/updater_binary/update_partitions.cpp | 3 ++- services/updater_binary/update_processor.cpp | 5 +++-- 8 files changed, 20 insertions(+), 22 deletions(-) diff --git a/services/applypatch/transfer_manager.cpp b/services/applypatch/transfer_manager.cpp index 6ba2e13d..f2281560 100644 --- a/services/applypatch/transfer_manager.cpp +++ b/services/applypatch/transfer_manager.cpp @@ -156,12 +156,10 @@ bool TransferManager::CheckResult(const CommandResult result, const std::string LOG(INFO) << "Running command need retry!"; UPDATER_CHECK_ONLY_RETURN(!globalParams->env, globalParams->env->PostMessage("retry_update", cmd)); return false; - break; case FAILED: default: LOG(ERROR) << "Running command failed"; return false; - break; } return true; } diff --git a/services/flashd/host/translate.cpp b/services/flashd/host/translate.cpp index dc7bc09d..a300c745 100755 --- a/services/flashd/host/translate.cpp +++ b/services/flashd/host/translate.cpp @@ -208,8 +208,6 @@ namespace TranslateCommand { TargetReboot(input.c_str(), outCmd); } else if (!strncmp(input.c_str(), CMDSTR_TARGET_MODE.c_str(), CMDSTR_TARGET_MODE.size())) { RunMode(input.c_str(), outCmd); - } else if (!strcmp(input.c_str(), CMDSTR_CONNECT_ANY.c_str())) { - outCmd->cmdFlag = CMD_KERNEL_TARGET_ANY; } else if (!strncmp(input.c_str(), CMDSTR_HILOG.c_str(), CMDSTR_HILOG.size())) { outCmd->cmdFlag = CMD_UNITY_HILOG; if (strstr(input.c_str(), " -v")) { diff --git a/services/package/pkg_algorithm/pkg_algo_digest.cpp b/services/package/pkg_algorithm/pkg_algo_digest.cpp index 0c1b8934..4bb6eef6 100644 --- a/services/package/pkg_algorithm/pkg_algo_digest.cpp +++ b/services/package/pkg_algorithm/pkg_algo_digest.cpp @@ -151,7 +151,6 @@ DigestAlgorithm::DigestAlgorithmPtr PkgAlgorithmFactory::GetDigestAlgorithm(uint return std::make_shared(); default: return std::make_shared(); - break; } return nullptr; } diff --git a/services/package/pkg_package/pkg_upgradefile.cpp b/services/package/pkg_package/pkg_upgradefile.cpp index 72e466ea..ecda48ae 100644 --- a/services/package/pkg_package/pkg_upgradefile.cpp +++ b/services/package/pkg_package/pkg_upgradefile.cpp @@ -129,10 +129,10 @@ int32_t UpgradePkgFile::SavePackage(size_t &signOffset) WriteLE32(reinterpret_cast(&header->updateFileVersion), pkgInfo_.updateFileVersion); int32_t ret = memcpy_s(header->softwareVersion, sizeof(header->softwareVersion), pkgInfo_.softwareVersion.data(), pkgInfo_.softwareVersion.size()); - PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret:%d", pkgStream_->GetFileName().c_str(), ret); + PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret: %d", pkgStream_->GetFileName().c_str(), ret); ret = memcpy_s(header->productUpdateId, sizeof(header->productUpdateId), pkgInfo_.productUpdateId.data(), pkgInfo_.productUpdateId.size()); - PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret:%d", pkgStream_->GetFileName().c_str(), ret); + PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret: %d", pkgStream_->GetFileName().c_str(), ret); offset += sizeof(UpgradePkgHeader); // 时间tlv WriteLE16(buffer.data() + offset, 0x02); // Type is 2 for time in TLV format @@ -140,16 +140,16 @@ int32_t UpgradePkgFile::SavePackage(size_t &signOffset) offset += sizeof(PkgTlv); UpgradePkgTime *time = reinterpret_cast(buffer.data() + offset); ret = memcpy_s(time->date, sizeof(time->date), pkgInfo_.date.data(), pkgInfo_.date.size()); - PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret:%d", pkgStream_->GetFileName().c_str(), ret); + PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret: %d", pkgStream_->GetFileName().c_str(), ret); ret = memcpy_s(time->time, sizeof(time->time), pkgInfo_.time.data(), pkgInfo_.time.size()); - PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret:%d", pkgStream_->GetFileName().c_str(), ret); + PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s %s ret: %d", pkgStream_->GetFileName().c_str(), ret); offset += sizeof(UpgradePkgTime); // 组件的tlv WriteLE16(buffer.data() + offset, 0x05); // Type is 5 for component in TLV format WriteLE16(buffer.data() + offset + sizeof(uint16_t), pkgInfo_.pkgInfo.entryCount * sizeof(UpgradeCompInfo)); offset += sizeof(PkgTlv); ret = pkgStream_->Write(buffer, UPGRADE_FILE_HEADER_LEN, 0); - PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail write upgrade file header for %s ret:%d", + PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail write upgrade file header for %s ret: %d", pkgStream_->GetFileName().c_str(), ret); // Clear buffer and save signature information @@ -374,7 +374,7 @@ int32_t UpgradeFileEntry::EncodeHeader(PkgStreamPtr inStream, size_t startOffset PKG_CHECK(ret == PKG_SUCCESS, return PKG_INVALID_PARAM, "outStream or inStream null for %s", fileName_.c_str()); ret = memcpy_s(comp.digest, sizeof(comp.digest), fileInfo_.digest, sizeof(fileInfo_.digest)); - PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret:%d", ret); + PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret: %d", ret); WriteLE32(reinterpret_cast(&comp.size), fileInfo_.fileInfo.unpackedSize); WriteLE16(reinterpret_cast(&comp.id), fileInfo_.id); WriteLE32(reinterpret_cast(&comp.originalSize), fileInfo_.originalSize); @@ -436,7 +436,7 @@ int32_t UpgradeFileEntry::DecodeHeader(const PkgBuffer &buffer, size_t headerOff fileInfo_.fileInfo.packMethod = PKG_COMPRESS_METHOD_NONE; fileInfo_.fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE; int32_t ret = memcpy_s(fileInfo_.digest, sizeof(fileInfo_.digest), info->digest, sizeof(info->digest)); - PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret:%d", ret); + PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret: %d", ret); PkgFile::ConvertBufferToString(fileInfo_.fileInfo.identity, {info->address, sizeof(info->address)}); PkgFile::ConvertBufferToString(fileInfo_.version, {info->version, sizeof(info->version)}); fileName_ = fileInfo_.fileInfo.identity; @@ -468,7 +468,7 @@ int32_t UpgradeFileEntry::Unpack(PkgStreamPtr outStream) 0, fileInfo_.fileInfo.digestMethod }; int32_t ret = memcpy_s(context.digest, sizeof(context.digest), fileInfo_.digest, sizeof(fileInfo_.digest)); - PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret:%d", ret); + PKG_CHECK(ret == EOK, return ret, "Fail to memcpy_s ret: %d", ret); ret = algorithm->Unpack(inStream, outStream, context); PKG_CHECK(ret == PKG_SUCCESS, return ret, "Fail Decompress for %s", fileName_.c_str()); PKG_LOGI("Unpack %s data offset:%zu packedSize:%zu unpackedSize:%zu", fileName_.c_str(), dataOffset_, diff --git a/services/ui/text_label.cpp b/services/ui/text_label.cpp index d94a90a6..6037f3e1 100644 --- a/services/ui/text_label.cpp +++ b/services/ui/text_label.cpp @@ -37,7 +37,6 @@ TextLabel::TextLabel(int mStartX, int mStartY, int w, int h, Frame *mparent) outlineColor_.b = 0x00; outlineColor_.a = 0x00; boldTopLine_ = false; - boldTopLine_ = false; const char midAlpha = 0xAA; actionBgColor_.r = 0x00; diff --git a/services/updater_binary/update_image_block.cpp b/services/updater_binary/update_image_block.cpp index cd042792..32ff33b9 100644 --- a/services/updater_binary/update_image_block.cpp +++ b/services/updater_binary/update_image_block.cpp @@ -345,11 +345,11 @@ int32_t UScriptInstructionBlockCheck::Execute(uscript::UScriptEnv &env, uscript: LOG(INFO) << "BlockSet::ReadDataFromBlock lseek64"; ret = lseek64(fd, static_cast(it->first * H_BLOCK_SIZE), SEEK_SET); UPDATER_ERROR_CHECK(ret != -1, "Failed to seek", - return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); + close(fd); return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); size_t size = (it->second - it->first) * H_BLOCK_SIZE; LOG(INFO) << "BlockSet::ReadDataFromBlock Read " << size << " from block"; UPDATER_ERROR_CHECK(utils::ReadFully(fd, block_buff.data() + pos, size), "Failed to read", - return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); + close(fd); return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); pos += size; } @@ -365,6 +365,7 @@ int32_t UScriptInstructionBlockCheck::Execute(uscript::UScriptEnv &env, uscript: } LOG(INFO) << "UScriptInstructionBlockCheck::Execute Success"; context.PushParam(USCRIPT_SUCCESS); + close(fd); return USCRIPT_SUCCESS; } @@ -405,11 +406,11 @@ int32_t UScriptInstructionShaCheck::Execute(uscript::UScriptEnv &env, uscript::U for (; it != blk.End(); ++it) { ret = lseek64(fd, static_cast(it->first * H_BLOCK_SIZE), SEEK_SET); UPDATER_ERROR_CHECK(ret != -1, "Failed to seek", - return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); + close(fd); return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); for (size_t i = it->first; i < it->second; ++i) { UPDATER_ERROR_CHECK(utils::ReadFully(fd, block_buff.data(), H_BLOCK_SIZE), "Failed to read", - return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); + close(fd); return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); SHA256_Update(&ctx, block_buff.data(), H_BLOCK_SIZE); } } @@ -417,9 +418,10 @@ int32_t UScriptInstructionShaCheck::Execute(uscript::UScriptEnv &env, uscript::U SHA256_Final(digest, &ctx); std::string resultSha = utils::ConvertSha256Hex(digest, SHA256_DIGEST_LENGTH); UPDATER_ERROR_CHECK(resultSha == contrastSha, "Different sha256, cannot continue", - return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); + close(fd); return ReturnAndPushParam(USCRIPT_ERROR_EXECUTE, context)); LOG(INFO) << "UScriptInstructionShaCheck::Execute Success"; context.PushParam(USCRIPT_SUCCESS); + close(fd); return USCRIPT_SUCCESS; } } diff --git a/services/updater_binary/update_partitions.cpp b/services/updater_binary/update_partitions.cpp index edd7fcab..89c13a31 100644 --- a/services/updater_binary/update_partitions.cpp +++ b/services/updater_binary/update_partitions.cpp @@ -117,7 +117,8 @@ int32_t UpdatePartitions::Execute(uscript::UScriptEnv &env, uscript::UScriptCont std::string tmpPath1 = tmpPath + filePath; ret = env.GetPkgManager()->CreatePkgStream(outStream, tmpPath1, info->unpackedSize, PkgStream::PkgStreamType_Write); - UPDATER_ERROR_CHECK(outStream != nullptr, "Error to create output stream", return USCRIPT_ERROR_EXECUTE); + UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS && outStream != nullptr, "Error to create output stream", + return USCRIPT_ERROR_EXECUTE); ret = env.GetPkgManager()->ExtractFile(filePath, outStream); UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS, "Error to extract file", env.GetPkgManager()->ClosePkgStream(outStream); return USCRIPT_ERROR_EXECUTE); diff --git a/services/updater_binary/update_processor.cpp b/services/updater_binary/update_processor.cpp index 34675148..8bcc08c0 100644 --- a/services/updater_binary/update_processor.cpp +++ b/services/updater_binary/update_processor.cpp @@ -146,7 +146,7 @@ int32_t UScriptInstructionRawImageWrite::Execute(uscript::UScriptEnv &env, uscri totalSize_ = info->unpackedSize; ret = env.GetPkgManager()->CreatePkgStream(outStream, imageFilename, RawImageWriteProcessor, writer.get()); - UPDATER_ERROR_CHECK(outStream != nullptr, "Error to create output stream", + UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS && outStream != nullptr, "Error to create output stream", DataWriter::ReleaseDataWriter(writer); return USCRIPT_ERROR_EXECUTE); ret = env.GetPkgManager()->ExtractFile(imageFilename, outStream); @@ -187,7 +187,8 @@ int32_t UScriptInstructionSparseImageWrite::Execute(uscript::UScriptEnv &env, us ret = env.GetPkgManager()->CreatePkgStream(outStream, partitionName, info->unpackedSize, PkgStream::PkgStreamType_MemoryMap); - UPDATER_ERROR_CHECK(outStream != nullptr, "Error to create output stream", return USCRIPT_ERROR_EXECUTE); + UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS && outStream != nullptr, "Error to create output stream", + return USCRIPT_ERROR_EXECUTE); ret = env.GetPkgManager()->ExtractFile(partitionName, outStream); UPDATER_ERROR_CHECK(ret == USCRIPT_SUCCESS, "Error to extract file", -- Gitee From 227327e96a4bc1d6b649712371381ade1cd36b4d Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Thu, 7 Apr 2022 17:17:25 +0800 Subject: [PATCH 82/94] Signed-off-by:hanqiaosheng updater drm init --- services/ui/drm_driver.cpp | 56 ++++++++++++++++++++++++++++++++++---- services/ui/drm_driver.h | 2 ++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 20119428..598ab6f2 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -72,6 +72,46 @@ int DrmDriver::ModesetCreateFb(struct BufferObject *bo) return 0; } +bool DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn, uint32_t &crtcId) +{ + // get possible crtc + drmModeEncoder *encoder = nullptr; + for (int i = 0; i < conn.count_encoders; i++) { + encoder = drmModeGetEncoder(fd, conn.encoders[i]); + if (encoder == nullptr) { + continue; + } + + for (int j = 0; j < res.count_crtc; j++) { + if ((encoder->possible_crtcs & (1u << (uint32_t)j)) != 0) { + crtcId = res.crtcs[j]; + drmModeFreeEncoder(encoder); + return true; + } + } + drmModeFreeEncoder(encoder); + encoder = nullptr; + } + return false; +} + +int DrmDriver::GetConnector(const drmModeRes &res, const int fd, uint32_t &connId) +{ + // get connected connector + for (int i = 0; i < res.count_connectors; i++) { + conn_ = drmModeGetConnector(fd, res.connectors[i]); + if (conn_ != nullptr && + conn_->connection == DRM_MODE_CONNECTED) { + connId = conn_->connector_id; + return true; + } + drmModeFreeConnector(conn_); + conn_ = nullptr; + } + + return false; +} + int DrmDriver::DrmInit(void) { fd_ = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); @@ -86,13 +126,17 @@ int DrmDriver::DrmInit(void) return -1; } - uint32_t crtcId = res_->crtcs[0]; - uint32_t connId = res_->connectors[1]; - conn_ = drmModeGetConnector(fd_, connId); - if (conn_ == nullptr) { - LOG(ERROR) << "drmModeGetConnector"; - return -1; + uint32_t crtcId; + uint32_t connId; + if (!GetConnector(*res_, fd_, connId)) { + LOG(ERROR) << "DrmInit cannot get drm connector"; + return -1; + } + if (GetCrtc(*res_, fd_, *conn_, crtcId)) { + LOG(ERROR) << "DrmInit cannot get drm crtc"; + return -1; } + buff_.width = conn_->modes[0].hdisplay; buff_.height = conn_->modes[0].vdisplay; diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h index 1e074929..075044f2 100644 --- a/services/ui/drm_driver.h +++ b/services/ui/drm_driver.h @@ -48,6 +48,8 @@ private: int ModesetCreateFb(struct BufferObject *bo); void ModesetDestroyFb(struct BufferObject *bo); int DrmInit(); + bool GetConnector(const drmModeRes &res, const int fd, uint32_t &connId); + bool GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn, uint32_t &crtcId); int fd_; drmModeConnector *conn_; drmModeRes *res_; -- Gitee From dd1a30c095048f9fac01cdb8a456a7089422c76f Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Thu, 7 Apr 2022 17:31:25 +0800 Subject: [PATCH 83/94] Signed-off-by:hanqiaosheng --- services/ui/drm_driver.cpp | 50 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 598ab6f2..9a31cbb5 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -77,36 +77,36 @@ bool DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const drmModeConnec // get possible crtc drmModeEncoder *encoder = nullptr; for (int i = 0; i < conn.count_encoders; i++) { - encoder = drmModeGetEncoder(fd, conn.encoders[i]); - if (encoder == nullptr) { - continue; - } - - for (int j = 0; j < res.count_crtc; j++) { - if ((encoder->possible_crtcs & (1u << (uint32_t)j)) != 0) { - crtcId = res.crtcs[j]; - drmModeFreeEncoder(encoder); - return true; - } - } - drmModeFreeEncoder(encoder); - encoder = nullptr; + encoder = drmModeGetEncoder(fd, conn.encoders[i]); + if (encoder == nullptr) { + continue; + } + + for (int j = 0; j < res.count_crtcs; j++) { + if ((encoder->possible_crtcs & (1u << (uint32_t)j)) != 0) { + crtcId = res.crtcs[j]; + drmModeFreeEncoder(encoder); + return true; + } + } + drmModeFreeEncoder(encoder); + encoder = nullptr; } return false; } -int DrmDriver::GetConnector(const drmModeRes &res, const int fd, uint32_t &connId) +bool DrmDriver::GetConnector(const drmModeRes &res, const int fd, uint32_t &connId) { // get connected connector for (int i = 0; i < res.count_connectors; i++) { - conn_ = drmModeGetConnector(fd, res.connectors[i]); - if (conn_ != nullptr && - conn_->connection == DRM_MODE_CONNECTED) { - connId = conn_->connector_id; - return true; - } - drmModeFreeConnector(conn_); - conn_ = nullptr; + conn_ = drmModeGetConnector(fd, res.connectors[i]); + if (conn_ != nullptr && + conn_->connection == DRM_MODE_CONNECTED) { + connId = conn_->connector_id; + return true; + } + drmModeFreeConnector(conn_); + conn_ = nullptr; } return false; @@ -130,11 +130,11 @@ int DrmDriver::DrmInit(void) uint32_t connId; if (!GetConnector(*res_, fd_, connId)) { LOG(ERROR) << "DrmInit cannot get drm connector"; - return -1; + return -1; } if (GetCrtc(*res_, fd_, *conn_, crtcId)) { LOG(ERROR) << "DrmInit cannot get drm crtc"; - return -1; + return -1; } buff_.width = conn_->modes[0].hdisplay; -- Gitee From 4bce5cf8257aa7a5ca177b3e8effc5f3ab2a3176 Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Sat, 9 Apr 2022 11:22:06 +0800 Subject: [PATCH 84/94] Signed-off-by:hanqiaosheng --- services/ui/drm_driver.cpp | 232 ++++++++++++++++++++++++++++++------- services/ui/drm_driver.h | 11 +- 2 files changed, 198 insertions(+), 45 deletions(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 9a31cbb5..3e77528b 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -72,10 +72,24 @@ int DrmDriver::ModesetCreateFb(struct BufferObject *bo) return 0; } -bool DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn, uint32_t &crtcId) +drmModeGetCrtc * DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn) { - // get possible crtc + // if connector has one encoder, use it drmModeEncoder *encoder = nullptr; + if (conn->encoder_id != 0) { + encoder = drmModeGetEncoder(fd, conn->encoder_id); + } + if (encoder != nullptr && encoder->crtc_id != 0) { + uint32_t crtcId = encoder->crtc_id; + drmModeFreeEncoder(encoder); + return drmModeGetCrtc(fd, crtcId); + } + + if (encoder != nullptr) { + drmModeFreeEncoder(encoder); + } + + // try get a vaild encoder and crtc for (int i = 0; i < conn.count_encoders; i++) { encoder = drmModeGetEncoder(fd, conn.encoders[i]); if (encoder == nullptr) { @@ -84,64 +98,180 @@ bool DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const drmModeConnec for (int j = 0; j < res.count_crtcs; j++) { if ((encoder->possible_crtcs & (1u << (uint32_t)j)) != 0) { - crtcId = res.crtcs[j]; - drmModeFreeEncoder(encoder); - return true; + if (res.crtcs[j] != 0) { + uint32_t crtcId = res.crtcs[j]; + drmModeFreeEncoder(encoder); + return drmModeGetCrtc(fd, crtcId); + } } } drmModeFreeEncoder(encoder); - encoder = nullptr; } - return false; + return nullptr; } -bool DrmDriver::GetConnector(const drmModeRes &res, const int fd, uint32_t &connId) +drmModeConnector * DrmDriver::GetFirstConnector(const drmModeRes &res, const int fd) { // get connected connector for (int i = 0; i < res.count_connectors; i++) { - conn_ = drmModeGetConnector(fd, res.connectors[i]); - if (conn_ != nullptr && - conn_->connection == DRM_MODE_CONNECTED) { - connId = conn_->connector_id; - return true; + drmModeConnector *conn = drmModeGetConnector(fd, res.connectors[i]); + if (conn == nullptr) { + continue; } - drmModeFreeConnector(conn_); - conn_ = nullptr; + if (conn->count_modes > 0 && + conn->connection == DRM_MODE_CONNECTED) { + return conn; + } + drmModeFreeConnector(conn); } + return nullptr; +} - return false; +drmModeConnector * DrmDriver::GetConnectorByType(const drmModeRes &res, const int fd, const uint32_t type) +{ + // get connected connector + for (int i = 0; i < res.count_connectors; i++) { + drmModeConnector *conn = drmModeGetConnector(fd, res.connectors[i]); + if (conn == nullptr) { + continue; + } + if (conn->connector_type == type && + conn->count_modes > 0 && + conn->connection == DRM_MODE_CONNECTED) { + return conn; + } + drmModeFreeConnector(conn); + } + return nullptr; } -int DrmDriver::DrmInit(void) + +drmModeConnector * DrmDriver::GetConnector(const drmModeRes &res, const int fd, uint32_t &modeId) { - fd_ = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); - if (fd_ < 0) { - LOG(ERROR) << "open failed"; - return -1; + // get main connector : lvds edp and dsi + uint32_t mainConnector[] = { + DRM_MODE_CONNECTOR_LVDS, + DRM_MODE_CONNECTOR_eDP, + DRM_MODE_CONNECTOR_DSI, + }; + + drmModeConnector *conn = nullptr; + for (int i = 0; i < sizeof(mainConnector) / sizeof(mainConnector[0]); i++) { + drmModeConnector *conn = GetConnectorByType(res, fd, mainConnector[i]); + if (conn != nullptr) + break; + } } - res_ = drmModeGetResources(fd_); - if (res_ == nullptr) { - LOG(ERROR) << "drmModeGetResources"; - return -1; + if (conn == nullptr) { + conn = GetFirstConnector(res, fd); + } + + if (conn == nullptr) { + LOG(ERROR) << "DrmDriver cannot get vaild connector"; + return nullptr; + } + + // get preferred mode index + modeId = 0; + for (int i = 0; i < conn->count_modes; i++) { + if ((conn->modes[i].type & DRM_MODE_TYPE_PREFERRED) != 0) + modeId = i; + break; + } + } + + return conn; +} + +drmModeRes * DrmDriver::GetResources(int &fd) +{ + // 1: open drm resource + drmModeRes res = nullptr; + for (int i = 0; i < DRM_MAX_MINOR; i++) { + res = GetOneResources(i, fd); + if (res != nullptr) { + break; + } } + return res; +} - uint32_t crtcId; - uint32_t connId; - if (!GetConnector(*res_, fd_, connId)) { - LOG(ERROR) << "DrmInit cannot get drm connector"; +drmModeRes * DrmDriver::GetOneResources(const int devIndex, int &fd) +{ + // 1: open drm device + std::string devName = DRM_DEV_NAME + "/card" + std::string(devIndex); + fd = open(devName, O_RDWR | O_CLOEXEC); + if (fd < 0) { + LOG(ERROR) << "open failed " << devName; + return nullptr; + } + // 2: check drm capacity + uint64_t cap = 0; + int ret = drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &cap); + if (ret != 0 || cap == 0) { + LOG(ERROR) << "drmGetCap failed"; + close(fd); + fd = -1; + return nullptr; + } + + // 3: get drm resources + drmModeRes *res = drmModeGetResources(fd); + if (res == nullptr) { + LOG(ERROR) << "drmModeGetResources failed"; + close(fd); + fd = -1; + return nullptr; + } + + // 4: check it has connected connector and crtc + if (res->count_crtcs > 0 && res->count_connectors > 0 && res->count_encoders > 0) { + drmModeConnector *conn = GetFirstConnector(res, fd); + if (conn != nullptr) { + // don't close fd + LOG(INFO) << "drm dev:" << devName; + drmModeFreeConnector(conn); + return res; + } + } + close(fd); + fd = -1; + drmModeFreeResources(res); + return nullptr; +} + +int DrmDriver::DrmInit(void) +{ + // 1: open drm resource + res_ = GetResources(fd_); + if (fd_ < 0 || res_ == nullptr) { + LOG(ERROR) << "DrmInit: GetResources failed"; return -1; } - if (GetCrtc(*res_, fd_, *conn_, crtcId)) { - LOG(ERROR) << "DrmInit cannot get drm crtc"; + + // 2 : get connected connector + uint32_t modeId; + conn_ = GetConnector(*res_, fd_, modeId); + if (conn_ == nullptr) { + LOG(ERROR) << "DrmInit: GetConnector failed"; return -1; } - buff_.width = conn_->modes[0].hdisplay; - buff_.height = conn_->modes[0].vdisplay; + // 3: get vaild encoder and crtc + crtc_ = GetCrtc(*res_, fd_, *conn_); + if (crtc_ == nullptr) { + LOG(ERROR) << "DrmInit: GetCrtc failed"; + return -1; + } + // 4: create userspace buffer + buff_.width = conn_->modes[modeId].hdisplay; + buff_.height = conn_->modes[modeId].vdisplay; ModesetCreateFb(&buff_); - drmModeSetCrtc(fd_, crtcId, buff_.fbId, 0, 0, &connId, 1, &conn_->modes[0]); + + // 5: bind ctrc and connector + drmModeSetCrtc(fd_, crtc_->crtc_id, buff_.fbId, 0, 0, &conn_->connector_id, 1, &conn_->modes[modeId]); LOG(INFO) << " drm init success."; return 0; } @@ -155,14 +285,32 @@ void DrmDriver::LoadDrmDriver() void DrmDriver::ModesetDestroyFb(struct BufferObject *bo) { - struct drm_mode_destroy_dumb destroy = {}; - drmModeRmFB(fd_, bo->fbId); - munmap(bo->vaddr, bo->size); - destroy.handle = bo->handle; - drmIoctl(fd_, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy); - drmModeFreeConnector(conn_); - drmModeFreeResources(res_); - close(fd_); + if (bo == nullptr) { + return; + } + if (fd_ > 0 && bo->fbId) { + drmModeRmFB(fd_, bo->fbId); + } + if (bo->vaddr != nullptr) { + munmap(bo->vaddr, bo->size); + } + if (bo->handle) { + struct drm_mode_destroy_dumb destroy = {}; + destroy.handle = bo->handle; + drmIoctl(fd_, DRM_IOCTL_GEM_CLOSE, &destroy); + } + if (crtc_ != nullptr) { + drmModeFreeCrtc(crtc_); + } + if (conn_ != nullptr) { + drmModeFreeConnector(conn_); + } + if (res_ != nullptr) { + drmModeFreeResources(res_); + } + if (fd_ > 0) { + close(fd_); + } } DrmDriver::~DrmDriver() diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h index 075044f2..40aa046d 100644 --- a/services/ui/drm_driver.h +++ b/services/ui/drm_driver.h @@ -40,7 +40,7 @@ struct BufferObject { class DrmDriver { protected: - DrmDriver() : fd_(-1), conn_(nullptr), res_(nullptr) {} + DrmDriver() : fd_(-1), conn_(nullptr), res_(nullptr), crtc_(nullptr) {} virtual ~DrmDriver(); void FlipBuffer(const void* buf); void LoadDrmDriver(); @@ -48,11 +48,16 @@ private: int ModesetCreateFb(struct BufferObject *bo); void ModesetDestroyFb(struct BufferObject *bo); int DrmInit(); - bool GetConnector(const drmModeRes &res, const int fd, uint32_t &connId); - bool GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn, uint32_t &crtcId); + drmModeGetCrtc *GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn); + drmModeConnector *GetFirstConnector(const drmModeRes &res, const int fd); + drmModeConnector *GetConnectorByType(const drmModeRes &res, const int fd, const uint32_t type); + drmModeConnector *GetConnector(const drmModeRes &res, const int fd, uint32_t &modeId); + drmModeRes *GetResources(int &fd); + drmModeRes *GetOneResources(const int devIndex, int &fd); int fd_; drmModeConnector *conn_; drmModeRes *res_; + drmModeRes *crtc_; struct BufferObject buff_ {}; }; } // namespace updater -- Gitee From f36e51bc522354047f7c63d3d8f16a1bd4496fcf Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Sat, 9 Apr 2022 14:47:03 +0800 Subject: [PATCH 85/94] Signed-off-by:hanqiaosheng --- services/ui/drm_driver.cpp | 42 ++++++++++++++++++++------------------ services/ui/drm_driver.h | 14 ++++++------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 3e77528b..aa8a4e26 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -72,19 +72,19 @@ int DrmDriver::ModesetCreateFb(struct BufferObject *bo) return 0; } -drmModeGetCrtc * DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn) +drmModeCrtc *DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn) const { // if connector has one encoder, use it drmModeEncoder *encoder = nullptr; - if (conn->encoder_id != 0) { - encoder = drmModeGetEncoder(fd, conn->encoder_id); + if (conn.encoder_id != 0) { + encoder = drmModeGetEncoder(fd, conn.encoder_id); } if (encoder != nullptr && encoder->crtc_id != 0) { uint32_t crtcId = encoder->crtc_id; drmModeFreeEncoder(encoder); return drmModeGetCrtc(fd, crtcId); } - + if (encoder != nullptr) { drmModeFreeEncoder(encoder); } @@ -110,7 +110,7 @@ drmModeGetCrtc * DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const d return nullptr; } -drmModeConnector * DrmDriver::GetFirstConnector(const drmModeRes &res, const int fd) +drmModeConnector *DrmDriver::GetFirstConnector(const drmModeRes &res, const int fd) const { // get connected connector for (int i = 0; i < res.count_connectors; i++) { @@ -127,7 +127,7 @@ drmModeConnector * DrmDriver::GetFirstConnector(const drmModeRes &res, const int return nullptr; } -drmModeConnector * DrmDriver::GetConnectorByType(const drmModeRes &res, const int fd, const uint32_t type) +drmModeConnector *DrmDriver::GetConnectorByType(const drmModeRes &res, const int fd, const uint32_t type) const { // get connected connector for (int i = 0; i < res.count_connectors; i++) { @@ -146,7 +146,7 @@ drmModeConnector * DrmDriver::GetConnectorByType(const drmModeRes &res, const in } -drmModeConnector * DrmDriver::GetConnector(const drmModeRes &res, const int fd, uint32_t &modeId) +drmModeConnector *DrmDriver::GetConnector(const drmModeRes &res, const int fd, uint32_t &modeId) const { // get main connector : lvds edp and dsi uint32_t mainConnector[] = { @@ -156,9 +156,9 @@ drmModeConnector * DrmDriver::GetConnector(const drmModeRes &res, const int fd, }; drmModeConnector *conn = nullptr; - for (int i = 0; i < sizeof(mainConnector) / sizeof(mainConnector[0]); i++) { - drmModeConnector *conn = GetConnectorByType(res, fd, mainConnector[i]); - if (conn != nullptr) + for (uint32_t i = 0; i < sizeof(mainConnector) / sizeof(mainConnector[0]); i++) { + conn = GetConnectorByType(res, fd, mainConnector[i]); + if (conn != nullptr) { break; } } @@ -175,19 +175,19 @@ drmModeConnector * DrmDriver::GetConnector(const drmModeRes &res, const int fd, // get preferred mode index modeId = 0; for (int i = 0; i < conn->count_modes; i++) { - if ((conn->modes[i].type & DRM_MODE_TYPE_PREFERRED) != 0) + if ((conn->modes[i].type & DRM_MODE_TYPE_PREFERRED) != 0) { modeId = i; break; } - } + } return conn; } -drmModeRes * DrmDriver::GetResources(int &fd) +drmModeRes *DrmDriver::GetResources(int &fd) const { // 1: open drm resource - drmModeRes res = nullptr; + drmModeRes *res = nullptr; for (int i = 0; i < DRM_MAX_MINOR; i++) { res = GetOneResources(i, fd); if (res != nullptr) { @@ -197,11 +197,11 @@ drmModeRes * DrmDriver::GetResources(int &fd) return res; } -drmModeRes * DrmDriver::GetOneResources(const int devIndex, int &fd) +drmModeRes *DrmDriver::GetOneResources(const int devIndex, int &fd) const { // 1: open drm device - std::string devName = DRM_DEV_NAME + "/card" + std::string(devIndex); - fd = open(devName, O_RDWR | O_CLOEXEC); + std::string devName = std::string("/dev/dri/card") + std::to_string(devIndex); + fd = open(devName.c_str(), O_RDWR | O_CLOEXEC); if (fd < 0) { LOG(ERROR) << "open failed " << devName; return nullptr; @@ -215,7 +215,7 @@ drmModeRes * DrmDriver::GetOneResources(const int devIndex, int &fd) fd = -1; return nullptr; } - + // 3: get drm resources drmModeRes *res = drmModeGetResources(fd); if (res == nullptr) { @@ -227,7 +227,7 @@ drmModeRes * DrmDriver::GetOneResources(const int devIndex, int &fd) // 4: check it has connected connector and crtc if (res->count_crtcs > 0 && res->count_connectors > 0 && res->count_encoders > 0) { - drmModeConnector *conn = GetFirstConnector(res, fd); + drmModeConnector *conn = GetFirstConnector(*res, fd); if (conn != nullptr) { // don't close fd LOG(INFO) << "drm dev:" << devName; @@ -269,9 +269,11 @@ int DrmDriver::DrmInit(void) buff_.width = conn_->modes[modeId].hdisplay; buff_.height = conn_->modes[modeId].vdisplay; ModesetCreateFb(&buff_); - + // 5: bind ctrc and connector drmModeSetCrtc(fd_, crtc_->crtc_id, buff_.fbId, 0, 0, &conn_->connector_id, 1, &conn_->modes[modeId]); + LOG(ERROR) << "DrmInit: buff_.width:" << buff_.width << " buff_.height:" << buff_.height; + LOG(ERROR) << "DrmInit: crtc_id:" << crtc_->crtc_id << " connector_id:" << conn_->connector_id; LOG(INFO) << " drm init success."; return 0; } diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h index 40aa046d..c0fcb38f 100644 --- a/services/ui/drm_driver.h +++ b/services/ui/drm_driver.h @@ -48,16 +48,16 @@ private: int ModesetCreateFb(struct BufferObject *bo); void ModesetDestroyFb(struct BufferObject *bo); int DrmInit(); - drmModeGetCrtc *GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn); - drmModeConnector *GetFirstConnector(const drmModeRes &res, const int fd); - drmModeConnector *GetConnectorByType(const drmModeRes &res, const int fd, const uint32_t type); - drmModeConnector *GetConnector(const drmModeRes &res, const int fd, uint32_t &modeId); - drmModeRes *GetResources(int &fd); - drmModeRes *GetOneResources(const int devIndex, int &fd); + drmModeCrtc *GetCrtc(const drmModeRes &res, const int fd, const drmModeConnector &conn) const; + drmModeConnector *GetFirstConnector(const drmModeRes &res, const int fd) const; + drmModeConnector *GetConnectorByType(const drmModeRes &res, const int fd, const uint32_t type) const; + drmModeConnector *GetConnector(const drmModeRes &res, const int fd, uint32_t &modeId) const; + drmModeRes *GetResources(int &fd) const; + drmModeRes *GetOneResources(const int devIndex, int &fd) const; int fd_; drmModeConnector *conn_; drmModeRes *res_; - drmModeRes *crtc_; + drmModeCrtcl *crtc_; struct BufferObject buff_ {}; }; } // namespace updater -- Gitee From 9ab34c45a7b2b426841f21668a24b5cb145dfc8e Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Sat, 9 Apr 2022 14:52:44 +0800 Subject: [PATCH 86/94] Signed-off-by:hanqiaosheng --- services/ui/drm_driver.cpp | 4 ++-- services/ui/drm_driver.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index aa8a4e26..eae48b9c 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -272,8 +272,8 @@ int DrmDriver::DrmInit(void) // 5: bind ctrc and connector drmModeSetCrtc(fd_, crtc_->crtc_id, buff_.fbId, 0, 0, &conn_->connector_id, 1, &conn_->modes[modeId]); - LOG(ERROR) << "DrmInit: buff_.width:" << buff_.width << " buff_.height:" << buff_.height; - LOG(ERROR) << "DrmInit: crtc_id:" << crtc_->crtc_id << " connector_id:" << conn_->connector_id; + LOG(INFO) << "DrmInit: buff_.width:" << buff_.width << " buff_.height:" << buff_.height; + LOG(INFO) << "DrmInit: crtc_id:" << crtc_->crtc_id << " connector_id:" << conn_->connector_id; LOG(INFO) << " drm init success."; return 0; } diff --git a/services/ui/drm_driver.h b/services/ui/drm_driver.h index c0fcb38f..2d10391f 100644 --- a/services/ui/drm_driver.h +++ b/services/ui/drm_driver.h @@ -57,7 +57,7 @@ private: int fd_; drmModeConnector *conn_; drmModeRes *res_; - drmModeCrtcl *crtc_; + drmModeCrtc *crtc_; struct BufferObject buff_ {}; }; } // namespace updater -- Gitee From e274bc6b25ce1436668ec7c154e42ce9693f00cd Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Sat, 9 Apr 2022 17:13:29 +0800 Subject: [PATCH 87/94] Signed-off-by:hanqiaosheng --- services/ui/drm_driver.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index eae48b9c..01a6e2e8 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -98,11 +98,8 @@ drmModeCrtc *DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const drmMo for (int j = 0; j < res.count_crtcs; j++) { if ((encoder->possible_crtcs & (1u << (uint32_t)j)) != 0) { - if (res.crtcs[j] != 0) { - uint32_t crtcId = res.crtcs[j]; - drmModeFreeEncoder(encoder); - return drmModeGetCrtc(fd, crtcId); - } + drmModeFreeEncoder(encoder); + return drmModeGetCrtc(fd, res.crtcs[j]); } } drmModeFreeEncoder(encoder); @@ -272,8 +269,8 @@ int DrmDriver::DrmInit(void) // 5: bind ctrc and connector drmModeSetCrtc(fd_, crtc_->crtc_id, buff_.fbId, 0, 0, &conn_->connector_id, 1, &conn_->modes[modeId]); - LOG(INFO) << "DrmInit: buff_.width:" << buff_.width << " buff_.height:" << buff_.height; - LOG(INFO) << "DrmInit: crtc_id:" << crtc_->crtc_id << " connector_id:" << conn_->connector_id; + LOG(ERROR) << "DrmInit: buff_.width:" << buff_.width << " buff_.height:" << buff_.height; + LOG(ERROR) << "DrmInit: crtc_id:" << crtc_->crtc_id << " connector_id:" << conn_->connector_id; LOG(INFO) << " drm init success."; return 0; } -- Gitee From 07c4fcd76d8804916673d3772bd7d5b2bd4e5507 Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Sat, 9 Apr 2022 17:17:44 +0800 Subject: [PATCH 88/94] Signed-off-by:hanqiaosheng --- services/ui/drm_driver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 01a6e2e8..43c4e6cd 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -269,8 +269,8 @@ int DrmDriver::DrmInit(void) // 5: bind ctrc and connector drmModeSetCrtc(fd_, crtc_->crtc_id, buff_.fbId, 0, 0, &conn_->connector_id, 1, &conn_->modes[modeId]); - LOG(ERROR) << "DrmInit: buff_.width:" << buff_.width << " buff_.height:" << buff_.height; - LOG(ERROR) << "DrmInit: crtc_id:" << crtc_->crtc_id << " connector_id:" << conn_->connector_id; + LOG(INFO) << "DrmInit: buff_.width:" << buff_.width << " buff_.height:" << buff_.height; + LOG(INFO) << "DrmInit: crtc_id:" << crtc_->crtc_id << " connector_id:" << conn_->connector_id; LOG(INFO) << " drm init success."; return 0; } -- Gitee From 67f6de95d7f6b3b3c1523a47eb997b0ac4954206 Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Mon, 11 Apr 2022 16:40:48 +0800 Subject: [PATCH 89/94] Signed-off-by:hanqiaosheng --- services/ui/drm_driver.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 43c4e6cd..2b9207f5 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -284,16 +284,13 @@ void DrmDriver::LoadDrmDriver() void DrmDriver::ModesetDestroyFb(struct BufferObject *bo) { - if (bo == nullptr) { - return; - } - if (fd_ > 0 && bo->fbId) { + if (fd_ > 0 && bo->fbId != 0) { drmModeRmFB(fd_, bo->fbId); } if (bo->vaddr != nullptr) { munmap(bo->vaddr, bo->size); } - if (bo->handle) { + if (fd_ > 0) { struct drm_mode_destroy_dumb destroy = {}; destroy.handle = bo->handle; drmIoctl(fd_, DRM_IOCTL_GEM_CLOSE, &destroy); -- Gitee From 1a1a6454153ef928c673ad177dc4cf392f326b91 Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Wed, 13 Apr 2022 15:14:29 +0800 Subject: [PATCH 90/94] Signed-off-by:hanqiaosheng --- services/ui/drm_driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 2b9207f5..724cf467 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -97,7 +97,7 @@ drmModeCrtc *DrmDriver::GetCrtc(const drmModeRes &res, const int fd, const drmMo } for (int j = 0; j < res.count_crtcs; j++) { - if ((encoder->possible_crtcs & (1u << (uint32_t)j)) != 0) { + if ((encoder->possible_crtcs & (1u << static_cast(j))) != 0) { drmModeFreeEncoder(encoder); return drmModeGetCrtc(fd, res.crtcs[j]); } -- Gitee From 7f9cd6dfa40bdd2ea1bd935008cefc1dd6eb726e Mon Sep 17 00:00:00 2001 From: hanqiaosheng Date: Thu, 14 Apr 2022 10:03:42 +0800 Subject: [PATCH 91/94] Signed-off-by:hanqiaosheng --- services/ui/drm_driver.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/services/ui/drm_driver.cpp b/services/ui/drm_driver.cpp index 724cf467..44a5ae01 100644 --- a/services/ui/drm_driver.cpp +++ b/services/ui/drm_driver.cpp @@ -197,43 +197,42 @@ drmModeRes *DrmDriver::GetResources(int &fd) const drmModeRes *DrmDriver::GetOneResources(const int devIndex, int &fd) const { // 1: open drm device + fd = -1; std::string devName = std::string("/dev/dri/card") + std::to_string(devIndex); - fd = open(devName.c_str(), O_RDWR | O_CLOEXEC); - if (fd < 0) { + int tmpFd = open(devName.c_str(), O_RDWR | O_CLOEXEC); + if (tmpFd < 0) { LOG(ERROR) << "open failed " << devName; return nullptr; } // 2: check drm capacity uint64_t cap = 0; - int ret = drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &cap); + int ret = drmGetCap(tmpFd, DRM_CAP_DUMB_BUFFER, &cap); if (ret != 0 || cap == 0) { LOG(ERROR) << "drmGetCap failed"; - close(fd); - fd = -1; + close(tmpFd); return nullptr; } // 3: get drm resources - drmModeRes *res = drmModeGetResources(fd); + drmModeRes *res = drmModeGetResources(tmpFd); if (res == nullptr) { LOG(ERROR) << "drmModeGetResources failed"; - close(fd); - fd = -1; + close(tmpFd); return nullptr; } // 4: check it has connected connector and crtc if (res->count_crtcs > 0 && res->count_connectors > 0 && res->count_encoders > 0) { - drmModeConnector *conn = GetFirstConnector(*res, fd); + drmModeConnector *conn = GetFirstConnector(*res, tmpFd); if (conn != nullptr) { // don't close fd LOG(INFO) << "drm dev:" << devName; drmModeFreeConnector(conn); + fd = tmpFd; return res; } } - close(fd); - fd = -1; + close(tmpFd); drmModeFreeResources(res); return nullptr; } -- Gitee From 0ab31d376e055f89e1a79be9915f704c3e88ecc1 Mon Sep 17 00:00:00 2001 From: chenzihan Date: Sat, 16 Apr 2022 13:50:03 +0800 Subject: [PATCH 92/94] Signed-off-by: chenzihan fix:fix adout user_wipe_data --- interfaces/kits/updaterkits/BUILD.gn | 1 + interfaces/kits/updaterkits/updaterkits.cpp | 9 +++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/interfaces/kits/updaterkits/BUILD.gn b/interfaces/kits/updaterkits/BUILD.gn index fd59e521..2c68114f 100755 --- a/interfaces/kits/updaterkits/BUILD.gn +++ b/interfaces/kits/updaterkits/BUILD.gn @@ -30,6 +30,7 @@ ohos_static_library("libupdaterkits") { "//third_party/bounds_checking_function:libsec_static", ] + external_deps = [ "init:libbegetutil" ] subsystem_name = "updater" part_name = "updater" } diff --git a/interfaces/kits/updaterkits/updaterkits.cpp b/interfaces/kits/updaterkits/updaterkits.cpp index bfc2a6a4..227621f5 100755 --- a/interfaces/kits/updaterkits/updaterkits.cpp +++ b/interfaces/kits/updaterkits/updaterkits.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "misc_info/misc_info.h" #include "parameters.h" #include "securec.h" @@ -38,12 +39,8 @@ static bool WriteToMiscAndRebootToUpdater(const std::string &miscFile, #ifndef UPDATER_UT int32_t propertyMaxSize = 92; char updateCmd[propertyMaxSize]; - void(snprintf_s(updateCmd, propertyMaxSize, propertyMaxSize - 1, "reboot,updater:%s", updateMsg.update)); - bool bRet = OHOS::system::SetParameter("ohos.startup.powerctrl", updateCmd); - if (!bRet) { - std::cout << "WriteToMiscAndRebootToUpdater SetParameter failed, errno: " << errno << std::endl; - return false; - } + void(snprintf_s(updateCmd, propertyMaxSize, propertyMaxSize - 1, "updater:%s", updateMsg.update)); + DoReboot(updateCmd); while (true) { pause(); } -- Gitee From 1f5d46ceac30d3ad3fe5c4f623385e79d459d6a2 Mon Sep 17 00:00:00 2001 From: chenzihan Date: Mon, 25 Apr 2022 11:07:25 +0800 Subject: [PATCH 93/94] Signed-off-by: chenzihan fix:codex --- services/applypatch/block_set.cpp | 6 ++++++ services/include/applypatch/block_set.h | 9 +++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/services/applypatch/block_set.cpp b/services/applypatch/block_set.cpp index b267cfb7..00971141 100644 --- a/services/applypatch/block_set.cpp +++ b/services/applypatch/block_set.cpp @@ -43,6 +43,12 @@ BlockSet::BlockSet(std::vector &&pairs) } } +BlockSet::~BlockSet() +{ + blockSize_ = 0; + blocks_.clear(); +} + bool BlockSet::CheckReliablePair(BlockPair pair) { UPDATER_ERROR_CHECK(pair.first < pair.second, "Invalid number of block size", return false); diff --git a/services/include/applypatch/block_set.h b/services/include/applypatch/block_set.h index a59f3956..6ee4bdb7 100644 --- a/services/include/applypatch/block_set.h +++ b/services/include/applypatch/block_set.h @@ -35,12 +35,9 @@ class Command; class BlockSet { public: - BlockSet() - { - blockSize_ = 0; - } - explicit BlockSet(std::vector &&pairs); + + ~BlockSet(); // Insert block to set after parsing from a string type or vector type bool ParserAndInsert(const std::string &blockStr); @@ -96,7 +93,7 @@ public: // write data to block size_t WriteDataToBlock(int fd, std::vector &buffer); protected: - size_t blockSize_; + size_t blockSize_ = 0; std::vector blocks_; private: void PushBack(BlockPair block_pair); -- Gitee From 9135dee2e946fb130524116a0de95f29ccdc7991 Mon Sep 17 00:00:00 2001 From: chenzihan Date: Mon, 25 Apr 2022 11:07:25 +0800 Subject: [PATCH 94/94] Signed-off-by: chenzihan fix:codex --- services/applypatch/block_set.cpp | 6 ++++++ services/include/applypatch/block_set.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/services/applypatch/block_set.cpp b/services/applypatch/block_set.cpp index b267cfb7..00971141 100644 --- a/services/applypatch/block_set.cpp +++ b/services/applypatch/block_set.cpp @@ -43,6 +43,12 @@ BlockSet::BlockSet(std::vector &&pairs) } } +BlockSet::~BlockSet() +{ + blockSize_ = 0; + blocks_.clear(); +} + bool BlockSet::CheckReliablePair(BlockPair pair) { UPDATER_ERROR_CHECK(pair.first < pair.second, "Invalid number of block size", return false); diff --git a/services/include/applypatch/block_set.h b/services/include/applypatch/block_set.h index a59f3956..2059cc66 100644 --- a/services/include/applypatch/block_set.h +++ b/services/include/applypatch/block_set.h @@ -41,6 +41,8 @@ public: } explicit BlockSet(std::vector &&pairs); + + ~BlockSet(); // Insert block to set after parsing from a string type or vector type bool ParserAndInsert(const std::string &blockStr); -- Gitee