diff options
Diffstat (limited to 'nsframework/backup_manager/server/src')
5 files changed, 3344 insertions, 0 deletions
diff --git a/nsframework/backup_manager/server/src/backupmanager_application.cpp b/nsframework/backup_manager/server/src/backupmanager_application.cpp new file mode 100644 index 00000000..c08e7256 --- /dev/null +++ b/nsframework/backup_manager/server/src/backupmanager_application.cpp @@ -0,0 +1,277 @@ +/* + * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. + * + * 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 <native_service/ns_backup.h> +#include <agl_thread.h> +#include <system_service/ss_system_if.h> +#include <system_service/ss_system_manager_notifications.h> +#include <native_service/frameworkunified_multithreading.h> + +#include <nv_hal.h> +#include <signal.h> +#include <cerrno> +#include <cstdio> +#include "bkup_api.h" +#include "bkup_param.h" +#include "bkup_backupmanagerlog.h" +#include "bkup_process.h" + +pthread_t g_work_thread_id = 0; +pthread_t g_delay_thread_id = 0; +pthread_t g_nand_thread_id = 0; +HANDLE g_msg_handle_thread = NULL; + +typedef void (* signal_handler)(int); + +void SignalHandlerFuncForMsgHandleThread(int signum) { + pthread_exit(0); +} + +EFrameworkunifiedStatus MsgHandleThreadStart(HANDLE h_app) { + signal_handler p_signal = SignalHandlerFuncForMsgHandleThread; + signal(SIGUSR1, p_signal); + + g_work_thread_id = pthread_self(); + + EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK; + // LCOV_EXCL_BR_START 4: NSFW error case + if ((e_status = FrameworkunifiedAttachCallbackToDispatcher(h_app, FRAMEWORKUNIFIED_ANY_SOURCE, BACKUP_CID, BkupHandler)) != eFrameworkunifiedStatusOK) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + // LCOV_EXCL_START 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedAttachCallbacksToDispatcher e_status:%d\n", e_status); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 4: NSFW error case + } + + return e_status; +} + +EFrameworkunifiedStatus MsgHandleThreadStop(HANDLE h_app) { + EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK; + return e_status; +} + +EFrameworkunifiedStatus FrameworkunifiedOnInitialization(HANDLE h_app) { + EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK; + pthread_attr_t t_attr; + pthread_t t; + + // LCOV_EXCL_BR_START 4: NSFW error case + if ((e_status = FrameworkunifiedRegisterServiceAvailabilityNotification(h_app, NTFY_BackupMgr_Availability)) != eFrameworkunifiedStatusOK) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + // LCOV_EXCL_START 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedRegisterServiceAvailabilityNotification e_status:%d\n", e_status); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 4: NSFW error case + } + + if (pthread_attr_init(&t_attr) < 0) { // LCOV_EXCL_BR_LINE 5:pthread_attr_init's error case. + // LCOV_EXCL_START 5:pthread_attr_init's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_attr_init:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5:pthread_attr_init's error case. + } + + // LCOV_EXCL_BR_START 5:pthread_attr_setinheritsched's error case. + if (pthread_attr_setinheritsched(&t_attr, PTHREAD_INHERIT_SCHED) < 0) { + // LCOV_EXCL_BR_STOP 5:pthread_attr_setinheritsched's error case. + // LCOV_EXCL_START 5:pthread_attr_setinheritsched's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_attr_setinheritsched:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5:pthread_attr_setinheritsched's error case. + } + + if (pthread_create(&t, &t_attr, BkupNandThread, NULL) < 0) { // LCOV_EXCL_BR_LINE 5:pthread_create's error case. + // LCOV_EXCL_START 5:pthread_create's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_create:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5:pthread_create's error case. + } + + if (pthread_create(&t, &t_attr, BkupDelayThread, NULL) < 0) { // LCOV_EXCL_BR_LINE 5:pthread_create's error case. + // LCOV_EXCL_START 5:pthread_create's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_create:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5:pthread_create's error case. + } + + e_status = InitNv(); + if (e_status != eFrameworkunifiedStatusOK) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "InitNv e_status:%d", e_status); + exit(EXIT_FAILURE); + } + + if (BckupParamInit() < 0) { // LCOV_EXCL_BR_LINE 5:C API's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + exit(EXIT_FAILURE); // LCOV_EXCL_LINE 5:C API's error case. + } + + // LCOV_EXCL_BR_START 4: NSFW error case + if ((e_status = FrameworkunifiedAttachCallbackToDispatcher(h_app, FRAMEWORKUNIFIED_ANY_SOURCE, BACKUP_CID, BkupHandler)) != eFrameworkunifiedStatusOK) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + // LCOV_EXCL_START 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedAttachCallbacksToDispatcher e_status:%d\n", e_status); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 4: NSFW error case + } + + + g_msg_handle_thread = FrameworkunifiedCreateChildThread(h_app, SERVICE_BACKUP_MANAGER_MSG_HANDLE_THREAD, MsgHandleThreadStart, MsgHandleThreadStop); // LCOV_EXCL_BR_LINE 11:Unexpected branch // NOLINT (whitespace/line_length) + if (g_msg_handle_thread == NULL) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + // LCOV_EXCL_START 4: NSFW error case. + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, + "Fail to create SERVICE_BACKUP_MANAGER_MSG_HANDLE_THREAD"); + // LCOV_EXCL_STOP 4: NSFW error case. + } else { + if (eFrameworkunifiedStatusOK != (e_status = FrameworkunifiedStartChildThread(h_app, g_msg_handle_thread, 0, NULL))) { // LCOV_EXCL_BR_LINE 4: NSFW error case. // NOLINT (whitespace/line_length) + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Fail to Start SERVICE_BACKUP_MANAGER_MSG_HANDLE_THREAD. Status:%#x", e_status); // LCOV_EXCL_LINE 4: NSFW error case. // NOLINT (whitespace/line_length) + } + } + + // LCOV_EXCL_BR_START 4: NSFW error case + if ((e_status = FrameworkunifiedSubscribeNotificationWithCallback(h_app, + NTFY_SSSystemMgrPowerOnOff, + bkup_power_handler)) != eFrameworkunifiedStatusOK) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedSubscribeNotificationWithCallback eStatus:%d", e_status); // LCOV_EXCL_LINE 4: NSFW error case. // NOLINT (whitespace/line_length) + } + + e_status = BkupInitHandler(h_app); // LCOV_EXCL_BR_LINE 11:unexpected branch + + // LCOV_EXCL_BR_START 4: NSFW error case + if ((e_status = FrameworkunifiedPublishServiceAvailability(h_app, TRUE)) != eFrameworkunifiedStatusOK) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + // LCOV_EXCL_START 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedPublishServiceAvailability e_status:%d\n", e_status); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 4: NSFW error case + } + + return e_status; +} + +// LCOV_EXCL_START 14 Resident process, not called by NSFW +EFrameworkunifiedStatus FrameworkunifiedOnDestroy(HANDLE h_app) { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "called"); + return eFrameworkunifiedStatusOK; +} +// LCOV_EXCL_STOP 14 Resident process, not called by NSFW + +EFrameworkunifiedStatus FrameworkunifiedOnStart(HANDLE h_app) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "called"); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + return eFrameworkunifiedStatusOK; +} + +EFrameworkunifiedStatus FrameworkunifiedOnStop(HANDLE h_app) { + EFrameworkunifiedStatus e_status = BkupTerminateHandler(h_app); + + if (FrameworkunifiedPublishServiceAvailability(h_app, FALSE) != eFrameworkunifiedStatusOK) { // LCOV_EXCL_BR_LINE 4: NSFW error case + // LCOV_EXCL_START 15:marco defined in "native_service/ns_logger_if.h" + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedPublishServiceAvailability fail\n"); + // LCOV_EXCL_STOP 15:marco defined in "native_service/ns_logger_if.h" + } + + // LCOV_EXCL_BR_START 4: NSFW error case + if (eFrameworkunifiedStatusOK == (FrameworkunifiedStopChildThread(h_app, g_msg_handle_thread, 0, NULL))) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + FrameworkunifiedDestroyChildThread(h_app, g_msg_handle_thread); + g_msg_handle_thread = NULL; + } + + int ret2 = pthread_kill(g_work_thread_id, SIGUSR1); + if (ESRCH == ret2) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __PRETTY_FUNCTION__, + "thread is already exit !"); + } else if (EINVAL == ret2) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __PRETTY_FUNCTION__, + "signal is invalid !"); + } else { + pthread_join(g_work_thread_id, NULL); + } + + ret2 = pthread_kill(g_nand_thread_id, SIGUSR1); + if (ESRCH == ret2) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __PRETTY_FUNCTION__, + "thread is already exit !"); + } else if (EINVAL == ret2) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __PRETTY_FUNCTION__, + "signal is invalid !"); + } else { + pthread_join(g_nand_thread_id, NULL); + } + + ret2 = pthread_kill(g_delay_thread_id, SIGUSR1); + if (ESRCH == ret2) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __PRETTY_FUNCTION__, + "thread is already exit !"); + } else if (EINVAL == ret2) { + FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __PRETTY_FUNCTION__, + "signal is invalid !"); + } else { + pthread_join(g_delay_thread_id, NULL); + } + + return e_status; +} + +EFrameworkunifiedStatus FrameworkunifiedOnPreStart(HANDLE hApp) { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "called"); + return eFrameworkunifiedStatusOK; +} + +EFrameworkunifiedStatus FrameworkunifiedOnPreStop(HANDLE hApp) { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "called"); + return eFrameworkunifiedStatusOK; +} + +EFrameworkunifiedStatus FrameworkunifiedOnBackgroundStart(HANDLE hApp) { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "called"); + return eFrameworkunifiedStatusOK; +} + +EFrameworkunifiedStatus FrameworkunifiedOnBackgroundStop(HANDLE hApp) { + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "called"); + return eFrameworkunifiedStatusOK; +} + +EFrameworkunifiedStatus FrameworkunifiedOnDebugDump(HANDLE h_app) { // LCOV_EXCL_START 7:debug code + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "called"); + return eFrameworkunifiedStatusOK; +} +// LCOV_EXCL_STOP 7:debug code + +EFrameworkunifiedStatus FrameworkunifiedCreateStateMachine(HANDLE h_app) { // LCOV_EXCL_START 7:debug code + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "called"); + return eFrameworkunifiedStatusOK; +} +// LCOV_EXCL_STOP 7:debug code diff --git a/nsframework/backup_manager/server/src/backupmanager_main.cpp b/nsframework/backup_manager/server/src/backupmanager_main.cpp new file mode 100644 index 00000000..f2255248 --- /dev/null +++ b/nsframework/backup_manager/server/src/backupmanager_main.cpp @@ -0,0 +1,61 @@ +/* + * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. + * + * 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 <native_service/ns_version_if.h> +#include <native_service/frameworkunified_dispatcher.h> +#include <agl_thread.h> +#include <system_service/ss_system_if.h> +#include <cerrno> +#include <cstdio> +#include "bkup_backupmanagerlog.h" + +CFrameworkunifiedVersion g_FrameworkunifiedVersion(0, 0, 0); // NOLINT(readability/nolint). + +FRAMEWORKUNIFIEDLOGPARAM g_FrameworkunifiedLogParams = { // NOLINT(readability/nolint) The varable is used by FW + FRAMEWORKUNIFIEDLOGOPTIONS, + { + ZONE_TEXT_10, ZONE_TEXT_11, ZONE_TEXT_12, + ZONE_TEXT_13, ZONE_TEXT_14, ZONE_TEXT_15, + ZONE_TEXT_16, ZONE_TEXT_17, ZONE_TEXT_18, + ZONE_TEXT_19, ZONE_TEXT_20, ZONE_TEXT_21, + ZONE_TEXT_22, ZONE_TEXT_23, ZONE_TEXT_24, + ZONE_TEXT_25, ZONE_TEXT_26, ZONE_TEXT_27, + ZONE_TEXT_28, ZONE_TEXT_29, ZONE_TEXT_30, + ZONE_TEXT_31 + }, + FRAMEWORKUNIFIEDLOGZONES +}; + +int main(int argc, char *argv[]) { + // LCOV_EXCL_BR_START 11:unexpected branch + FrameworkunifiedDefaultCallbackHandler cb_funcs; + FRAMEWORKUNIFIED_MAKE_DEFAULT_CALLBACK(cb_funcs); + FRAMEWORKUNIFIED_SET_ZONES(); + // LCOV_EXCL_BR_STOP 11:unexpected branch + + // LCOV_EXCL_BR_START 11:unexpected branch + EFrameworkunifiedStatus e_status = FrameworkunifiedDispatcherWithArguments(MN_NS_BACKUPMGR, argc, argv, &cb_funcs); + // LCOV_EXCL_BR_STOP 11:unexpected branch + if (e_status != eFrameworkunifiedStatusOK) { // LCOV_EXCL_BR_LINE 4: NSFW error case + // LCOV_EXCL_START 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedDispatcherWithArguments: %d", e_status); + return EXIT_FAILURE; + // LCOV_EXCL_STOP 4: NSFW error case + } + + return EXIT_SUCCESS; +} // LCOV_EXCL_BR_LINE 10:The final line diff --git a/nsframework/backup_manager/server/src/bkup_crc32.cpp b/nsframework/backup_manager/server/src/bkup_crc32.cpp new file mode 100644 index 00000000..f1d8449c --- /dev/null +++ b/nsframework/backup_manager/server/src/bkup_crc32.cpp @@ -0,0 +1,62 @@ +/* + * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. + * + * 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 <cstdio> +#include "bkup_crc32.h" +#include "bkup_util.h" + +/* + * CRC-32C lookup table + * + * Polynomial 0x1EDC6F41 + */ +static const uint32_t kBkupCrc32Lookup[4][256] = { + { + }, + { + }, + { + }, + { + } +}; + +/** + * compute CRC-32C (Slicing-by-4) + */ +uint32_t BkupCrc32(const void *data, size_t length) { + uint32_t crc = 0xFFFFFFFF; + const uint32_t *current = (const uint32_t *)data; + + if (data == NULL) { + return -1; + } + while (length >= 4) { + uint32_t one = *current++ ^ crc; + crc = kBkupCrc32Lookup[0][(one >> 24) & 0xFF] ^ + kBkupCrc32Lookup[1][(one >> 16) & 0xFF] ^ + kBkupCrc32Lookup[2][(one >> 8) & 0xFF] ^ + kBkupCrc32Lookup[3][one & 0xFF]; + length -= 4; + } + + const uint8_t *current_char = (const uint8_t *)current; + while (length-- > 0) { + crc = (crc >> 8) ^ kBkupCrc32Lookup[0][(crc & 0xFF) ^ *current_char++]; + } + + return ~crc; +} diff --git a/nsframework/backup_manager/server/src/bkup_param.cpp b/nsframework/backup_manager/server/src/bkup_param.cpp new file mode 100644 index 00000000..900779ba --- /dev/null +++ b/nsframework/backup_manager/server/src/bkup_param.cpp @@ -0,0 +1,447 @@ +/* + * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. + * + * 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 <other_service/VP_GetEnv.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <stdlib.h> +#include <unistd.h> +#include <libxml/xmlerror.h> +#include <libxml/parser.h> +#include <libxml/SAX2.h> +#include <inttypes.h> +#include <cerrno> +#include <cstdio> +#include <string> +#include <map> +#include <utility> +#include "bkup_param.h" +#include "bkup_backupmanagerlog.h" +#include "bkup_util.h" + +#define BKUP_XML_PATH_MAX 100 +#define BKUP_XML_PATH "/usr/agl/conf/BS/ns/backup_manager/rodata/" +#define BKUP_XML_PREFIX "backup_" +#define BKUP_XML_EXTENSION ".xml" + +#define BKUP_AREA_1 "AREA1" +#define BKUP_AREA_2 "AREA2" +#define BKUP_BRAND_1 "BRAND1" +#define BKUP_BRAND_2 "BRAND2" +#define BKUP_GRADE_1 "GRADE1" +#define BKUP_GRADE_2 "GRADE2" +#define BKUP_DESTINATION_TYPE_AREA1_TE "AREA1_TE" +#define BKUP_DESTINATION_TYPE_AREA1_L "AREA1_L" +#define BKUP_DESTINATION_TYPE_AREA2_T "AREA2_T" +#define BKUP_DESTINATION_TYPE_AREA2_TE "AREA2_TE" + +#define BKUP_DESTINATION_STR_MAX 10 +typedef struct { + char area[VP_MAX_LENGTH]; + char brand[VP_MAX_LENGTH]; + char grade[VP_MAX_LENGTH]; + char destination[BKUP_DESTINATION_STR_MAX]; +} BkupDestinationTbl; + +const BkupDestinationTbl kDestinationTbl[] = { + // Destination:Area1 + {BKUP_AREA_1, BKUP_BRAND_1, BKUP_GRADE_1, BKUP_DESTINATION_TYPE_AREA1_TE}, + {BKUP_AREA_1, BKUP_BRAND_1, BKUP_GRADE_2, BKUP_DESTINATION_TYPE_AREA1_TE}, + {BKUP_AREA_1, BKUP_BRAND_2, BKUP_GRADE_1, BKUP_DESTINATION_TYPE_AREA1_L}, + {BKUP_AREA_1, BKUP_BRAND_2, BKUP_GRADE_2, BKUP_DESTINATION_TYPE_AREA1_L}, + // Destination:Area2 + {BKUP_AREA_2, BKUP_BRAND_1, BKUP_GRADE_1, BKUP_DESTINATION_TYPE_AREA2_TE}, + {BKUP_AREA_2, BKUP_BRAND_1, BKUP_GRADE_2, BKUP_DESTINATION_TYPE_AREA2_TE}, + {BKUP_AREA_2, BKUP_BRAND_2, BKUP_GRADE_1, BKUP_DESTINATION_TYPE_AREA2_T}, + {BKUP_AREA_2, BKUP_BRAND_2, BKUP_GRADE_2, BKUP_DESTINATION_TYPE_AREA2_T}, +}; + +typedef std::string Category; +typedef struct { + bool nand; + bool cache_dram; + bool backup_dram; + bool sync; + bool encrypt; + int backup_cycle; +} CategoryProperty; +typedef std::map<Category, CategoryProperty> CategoryTable; + +typedef std::string Item; +typedef struct { + int id; + int size; + void *opt; + Category category; +} ItemProperty; // LCOV_EXCL_BR_LINE 11:except,C++ STL +typedef std::map<Item, ItemProperty> ItemTable; +typedef std::map<int, Item> IdTable; + +typedef struct { + Category current; + CategoryTable category_table; + ItemTable item_table; + IdTable id_table; +} BackupParams; // LCOV_EXCL_BR_LINE 11:except,C++ STL + +static BackupParams *g_backup_params = NULL; + +static void StartElementNs(void *ctx, const xmlChar *localname, + const xmlChar *prefix, const xmlChar *uri, + int nb_namespaces, const xmlChar **namespaces, + int nb_attributes, int nb_defaulted, + const xmlChar **attributes) { + if (ctx == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "ctx is NULL"); + return; + } + if (localname == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "localname is NULL"); + return; + } + BackupParams *p_backup_params = static_cast<BackupParams *>(ctx); + std::string tag = (const char *)localname; // LCOV_EXCL_BR_LINE 11:except,C++ STL + if (tag.compare("backup") == 0) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + // do nothing + } else if (tag.compare("category") == 0) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + CategoryProperty category_attr = {false, false, false, false, false, 0}; + std::string category_name; // LCOV_EXCL_BR_LINE 11:except,C++ STL + + for (int i = 0; i < nb_attributes; i++) { + // LCOV_EXCL_BR_START 11:except,C++ STL + std::string localname = (const char *)attributes[i * 5]; + std::string value((const char *)attributes[i * 5 + 3], (const char *)attributes[i * 5 + 4]); + if (localname.compare("name") == 0) { + category_name = value; + } else if (localname.compare("nand") == 0) { + if (value.compare("true") == 0) { + category_attr.nand = true; + } + } else if (localname.compare("backupDram") == 0) { + if (value.compare("true") == 0) { + category_attr.backup_dram = true; + } + } else if (localname.compare("cacheDram") == 0) { + if (value.compare("true") == 0) { + category_attr.cache_dram = true; + } + } else if (localname.compare("sync") == 0) { + if (value.compare("true") == 0) { + category_attr.sync = true; + } + } else if (localname.compare("encrypt") == 0) { + if (value.compare("true") == 0) { + category_attr.encrypt = true; + } + } else if (localname.compare("backupCycle") == 0) { + category_attr.backup_cycle = atoi(value.c_str()); + // LCOV_EXCL_BR_STOP 11:except,C++ STL + } else { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __func__, "Unknown attribute:%s", localname.c_str()); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + } + } + + // LCOV_EXCL_BR_START 11:except,C++ STL + CategoryTable::iterator c_it = p_backup_params->category_table.find(category_name); + // LCOV_EXCL_BR_STOP 11:except,C++ STL + if (c_it != p_backup_params->category_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + // LCOV_EXCL_START 200:Execute in server start period + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "duplicate category:%s", category_name.c_str()); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 200:Execute in server start period + } + // LCOV_EXCL_BR_START 11:except,C++ STL + p_backup_params->category_table.insert(std::make_pair(category_name, category_attr)); + // LCOV_EXCL_BR_STOP 11:except,C++ STL + p_backup_params->current = category_name; // LCOV_EXCL_BR_LINE 11:except,C++ STL + } else if (tag.compare("item") == 0) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + if (p_backup_params->current.compare("") == 0) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + // LCOV_EXCL_START 200:Execute in server start period + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Detect item before category"); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 200:Execute in server start period + } + + ItemProperty item_property = {0, 0, NULL, p_backup_params->current}; // LCOV_EXCL_BR_LINE 11:except,C++ STL + std::string item_name; // LCOV_EXCL_BR_LINE 11:except,C++ STL + + for (int i = 0; i < nb_attributes; i++) { + // LCOV_EXCL_BR_START 11:except,C++ STL + std::string localname = (const char *)attributes[i * 5]; + std::string value((const char *)attributes[i * 5 + 3], (const char *)attributes[i * 5 + 4]); + if (localname.compare("name") == 0) { + item_name = value; + } else if (localname.compare("id") == 0) { + item_property.id = atoi(value.c_str()); + } else if (localname.compare("size") == 0) { + item_property.size = atoi(value.c_str()); + // LCOV_EXCL_BR_STOP 11:except,C++ STL + } else { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __func__, "Unknown attribute:%s", localname.c_str()); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + } + } + + ItemTable::iterator i_it = p_backup_params->item_table.find(item_name); // LCOV_EXCL_BR_LINE 11:except,C++ STL + if (i_it != p_backup_params->item_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + // LCOV_EXCL_START 200:Execute in server start period + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Duplicate item:%s", item_name.c_str()); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 200:Execute in server start period + } + // LCOV_EXCL_BR_START 11:except,C++ STL + p_backup_params->item_table.insert(std::make_pair(item_name, item_property)); + // LCOV_EXCL_BR_STOP 11:except,C++ STL + + IdTable::iterator id_it = p_backup_params->id_table.find(item_property.id); // LCOV_EXCL_BR_LINE 11:except,C++ STL + if (id_it != p_backup_params->id_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + // LCOV_EXCL_START 200:Execute in server start period + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Duplicate id:%d", item_property.id); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 200:Execute in server start period + } + // LCOV_EXCL_BR_START 11:except,C++ STL + p_backup_params->id_table.insert(std::make_pair(item_property.id, item_name)); + // LCOV_EXCL_BR_STOP 11:except,C++ STL + } else { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __func__, "Unknown tag:%s", localname); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + } +} + +static int BkupGetXmlPath(char* path) { + if (path == NULL) { // LCOV_EXCL_BR_LINE 6:Excluded as no NULL is currently passed + // LCOV_EXCL_START 6:Excluded as no NULL is currently passed + AGL_ASSERT_NOT_TESTED(); + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "path is NULL"); + return -1; + // LCOV_EXCL_STOP 6:Excluded as no NULL is currently passed + } + memset(path, 0, BKUP_XML_PATH_MAX); + char param_area[VP_MAX_LENGTH] = ""; + VP_GetEnv(VP_VEHICLEPARAMETERLIBRARY_AREA, param_area); + char param_brand[VP_MAX_LENGTH] = ""; + VP_GetEnv(VEHICLEPARAMETERLIBRARY_BRAND, param_brand); + char param_grade[VP_MAX_LENGTH] = ""; + VP_GetEnv(VP_VEHICLEPARAMETERLIBRARY_GRADE, param_grade); + + bool is_match = false; + for (uint16_t i = 0; i < _countof(kDestinationTbl); i++) { + size_t area_size = static_cast<size_t>(std::string(kDestinationTbl[i].area).size()); + // Check vehicle parameter settings (For VP_VEHICLEPARAMETERLIBRALY_AREA only, check the area size of tbl to check the character strings common to each area) + if ((strncmp(param_area, kDestinationTbl[i].area, area_size) == 0) && + (strncmp(param_brand, kDestinationTbl[i].brand, sizeof(param_area)) == 0) && + (strncmp(param_grade, kDestinationTbl[i].grade, sizeof(param_area)) == 0)) { + is_match = true; + snprintf(path, BKUP_XML_PATH_MAX, "%s%s%s%s", BKUP_XML_PATH, BKUP_XML_PREFIX, + kDestinationTbl[i].destination, BKUP_XML_EXTENSION); + break; + } + } + if (is_match == false) { + // If the destination settings do not match, set the AREA2_T path as failsafe + snprintf(path, BKUP_XML_PATH_MAX, "%s%s%s%s", BKUP_XML_PATH, BKUP_XML_PREFIX, + BKUP_DESTINATION_TYPE_AREA2_T, BKUP_XML_EXTENSION); + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Unexpected VP area[%s] brand[%s] grade[%s]", + param_area, param_brand, param_grade); + } + return 0; +} + +int BckupParamInit(void) { + int ret = -1; + xmlParserCtxtPtr xmlctx; + xmlSAXHandler saxh; + xmlDocPtr doc; + int fd = -1; + struct stat sb; + char *map = NULL; + uint64_t start, end; + + g_backup_params = new BackupParams; // LCOV_EXCL_BR_LINE 11:except,C++ operator + + LIBXML_TEST_VERSION // LCOV_EXCL_BR_LINE 11:unexpected branch + // LCOV_EXCL_BR_START 11:unexpected branch + xmlInitParser(); // NOLINT(readability/nolint) Defined in library of libxml + // LCOV_EXCL_BR_STOP 11:unexpected branch + + memset(&saxh, 0, sizeof(saxh)); + saxh.initialized = XML_SAX2_MAGIC; + saxh.startElementNs = StartElementNs; + + xmlctx = xmlCreatePushParserCtxt(&saxh, g_backup_params, NULL, 0, NULL); // LCOV_EXCL_BR_LINE 11:unexpected branch + + char xml_path[BKUP_XML_PATH_MAX] = {0}; + ret = BkupGetXmlPath(xml_path); + if (ret != 0) { // LCOV_EXCL_BR_LINE 6:Excluded because the return value does not cause an error + // LCOV_EXCL_START 6:Excluded because the return value does not cause an error + AGL_ASSERT_NOT_TESTED(); + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "BkupGetXmlPath Error"); + goto exit; + // LCOV_EXCL_STOP 6:Excluded because the return value does not cause an error + } + + if ((fd = open(xml_path, O_RDONLY)) < 0) { // LCOV_EXCL_BR_LINE 5:open's error case. + // LCOV_EXCL_START 5:open's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "open:%s", strerror(errno)); + goto exit; + // LCOV_EXCL_STOP 5:open's error case. + } + if (fstat(fd, &sb) < 0) { // LCOV_EXCL_BR_LINE 5:fstat's error case. + // LCOV_EXCL_START 5:fstat's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "fstat:%s", strerror(errno)); + goto exit; + // LCOV_EXCL_STOP 5:fstat's error case. + } + map = reinterpret_cast<char *>(mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)); + if (map == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + // LCOV_EXCL_START 5:mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:%s", strerror(errno)); + goto exit; + // LCOV_EXCL_STOP 5:mmap's error case. + } + + start = BkupTimerReal(); + if (xmlParseChunk(xmlctx, map, static_cast<int>(sb.st_size), 1)) { // LCOV_EXCL_BR_LINE 5:xmlParseChunk's error case. + // LCOV_EXCL_START 5:xmlParseChunk's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + xmlParserError(xmlctx, "xmlParseChunk"); + goto exit; + // LCOV_EXCL_STOP 5:xmlParseChunk's error case. + } + end = BkupTimerReal(); + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "spent:%" PRIu64 ".%06" PRIu64 "ms", + static_cast<uint64_t>((end - start) / 1000000), + static_cast<uint64_t>((end - start) % 1000000)); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + + doc = xmlctx->myDoc; + xmlFreeParserCtxt(xmlctx); // LCOV_EXCL_BR_LINE 11:unexpected branch + xmlFreeDoc(doc); // LCOV_EXCL_BR_LINE 11:unexpected branch + xmlCleanupParser(); // LCOV_EXCL_BR_LINE 11:unexpected branch + ret = 0; + +exit: + if (fd >= 0) { // LCOV_EXCL_BR_LINE 5:open's error case. + if (close(fd) < 0) { // LCOV_EXCL_BR_LINE 5:close's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, "close:%s", strerror(errno)); // LCOV_EXCL_LINE 5:close's error case. + } + } + if (map) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + if (munmap(map, sb.st_size) < 0) { // LCOV_EXCL_BR_LINE 5:munmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, "munmap:%s", strerror(errno)); // LCOV_EXCL_LINE 5:munmap's error case. + } + } + return ret; +} + +int BkupParamGet(const char *item_name, bkup_query_result_t *result) { + if (g_backup_params == NULL) { // LCOV_EXCL_BR_LINE 6:g_backup_params will not be NULL + // LCOV_EXCL_START 6:g_backup_params will not be NULL + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Uninitialize call"); + return -1; + // LCOV_EXCL_STOP 6:g_backup_params will not be NULL + } + if (result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "result is NULL"); + return -1; + } + ItemTable::iterator item_it = g_backup_params->item_table.find(item_name); // LCOV_EXCL_BR_LINE 11:except,C++ STL + if (item_it == g_backup_params->item_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + return -1; + } + + // LCOV_EXCL_BR_START 11:except,C++ STL + CategoryTable::iterator category_it = g_backup_params->category_table.find(item_it->second.category); + // LCOV_EXCL_BR_STOP 11:except,C++ STL + if (category_it == g_backup_params->category_table.end()) { // LCOV_EXCL_BR_LINE 6:double check + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + return -1; // LCOV_EXCL_LINE 6:double check + } + + // LCOV_EXCL_BR_START 11:except,C++ STL + result->id = item_it->second.id; + result->size = item_it->second.size; + result->opt = item_it->second.opt; + result->nand = category_it->second.nand; + result->cache_dram = category_it->second.cache_dram; + result->backup_dram = category_it->second.backup_dram; + result->sync = category_it->second.sync; + result->encrypt = category_it->second.encrypt; + result->backup_cycle = category_it->second.backup_cycle; + BkupStrlcpy(result->category_name, item_it->second.category.c_str(), sizeof(result->category_name)); + // LCOV_EXCL_BR_STOP 11:except,C++ STL + + return 0; +} + +int BkupParamGetNumid(uint32_t num_id, bkup_query_result_t *result, + char *item_name, size_t item_name_size) { + if (g_backup_params == NULL) { // LCOV_EXCL_BR_LINE 6:g_backup_params will not be NULL + // LCOV_EXCL_START 6:g_backup_params will not be NULL + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Uninitialize call"); + return -1; + // LCOV_EXCL_STOP 6:g_backup_params will not be NULL + } + + // LCOV_EXCL_BR_START 11:except,C++ STL + IdTable::iterator id_it = g_backup_params->id_table.find(static_cast<int>(num_id)); + // LCOV_EXCL_BR_STOP 11:except,C++ STL + if (id_it == g_backup_params->id_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + return -1; + } + BkupStrlcpy(item_name, id_it->second.c_str(), item_name_size); // LCOV_EXCL_BR_LINE 11:except,C++ STL + + return BkupParamGet(id_it->second.c_str(), result); // LCOV_EXCL_BR_LINE 11:except,C++ STL +} + +void *BkupParamSetOpt(const char *item_name, void *opt) { + if (g_backup_params == NULL) { // LCOV_EXCL_BR_LINE 6:g_backup_params will not be NULL + // LCOV_EXCL_START 6:g_backup_params will not be NULL + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Uninitialize call"); + return reinterpret_cast<void *>((-1)); + // LCOV_EXCL_STOP 6:g_backup_params will not be NULL + } + + ItemTable::iterator item_it = g_backup_params->item_table.find(item_name); // LCOV_EXCL_BR_LINE 11:except,C++ STL + if (item_it == g_backup_params->item_table.end()) { // LCOV_EXCL_BR_LINE 6:double check + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + return reinterpret_cast<void *>((-1)); // LCOV_EXCL_LINE 6:double check + } + + // LCOV_EXCL_BR_START 11:unexpected branch + return __sync_val_compare_and_swap(&item_it->second.opt, NULL, opt); // NOLINT(readability/nolint) Supplied by gcc + // LCOV_EXCL_BR_STOP 11:unexpected branch +} diff --git a/nsframework/backup_manager/server/src/bkup_process.cpp b/nsframework/backup_manager/server/src/bkup_process.cpp new file mode 100644 index 00000000..f8032efd --- /dev/null +++ b/nsframework/backup_manager/server/src/bkup_process.cpp @@ -0,0 +1,2497 @@ +/* + * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. + * + * 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 <dirent.h> +#include <fcntl.h> +#include <libgen.h> +#include <inttypes.h> +#include <mqueue.h> +#include <agl_thread.h> +#include <poll.h> +#include <signal.h> +#include <sys/epoll.h> +#include <sys/eventfd.h> +#include <sys/prctl.h> +#include <sys/stat.h> +#include <sys/syscall.h> +#include <sys/timerfd.h> +#include <sys/types.h> +#include <unistd.h> +#include <native_service/frameworkunified_framework_if.h> +#include <system_service/ss_system_manager_if.h> +#include <nv_hal.h> +#include <aglpath.h> +#include <cerrno> +#include <cstdio> +#include <map> +#include <set> +#include <string> +#include <utility> +#include "bkup_api.h" +#include "bkup_backupmanagerlog.h" +#include "bkup_param.h" +#include "bkup_crc32.h" +#include "bkup_util.h" + +#define BKUP_THREAD_NAND "NS_BkupNAND" +#define BKUP_THREAD_DELAY "NS_BkupDelay" +const char kBkupPrexixEncryption[] = "ENC_"; +const size_t kBkupPrexixEncryptionSize = 4; + +typedef void (* signal_handler)(int); +extern void SignalHandlerFuncForMsgHandleThread(int signum); +extern pthread_t g_delay_thread_id; +extern pthread_t g_nand_thread_id; + +#define MAX_FD_EPOLL 8 + +/** + * internal state + */ +typedef enum { + BKUP_STATE_INIT = 0, + BKUP_STATE_NORMAL, + BKUP_STATE_TERM, +} bkup_state_t; +static bkup_state_t g_bkup_internal_state = BKUP_STATE_INIT; + + +/** + * delay thread command + */ +typedef enum { + BKUP_DELAY_CMD_TERM = 0, + BKUP_DELAY_CMD_PRE_ACCOFF, + BKUP_DELAY_CMD_REGIST, +} bkup_delay_cmd_t; + + +/** + * inter thread communication message + */ +typedef union { + struct { + char client_name[16]; + uint32_t seq_id; + char *rcv_buf; + int rcv_size; + } nand; + struct { + +// bool terminate; + bkup_delay_cmd_t cmd; + + int event_fd; + char item_name[64]; + } delay; +} bkup_itc_message_t; + +/** + * reference response function + */ +typedef struct { + int (*set_response)(void *, void *, int, EFrameworkunifiedStatus); + void *opt; +} bkup_response_t; + +/** + * response MQ map(TLS) + */ +typedef std::map<std::string, HANDLE> g_bkup_response_mq_t; +static __thread g_bkup_response_mq_t *g_bkup_response_mq; + +/** + * NAND thread itc MQ + */ +static mqd_t g_bkup_nand_mqd = -1; + +/** + * Delay thread itc MQ + */ +static mqd_t g_bkup_delay_mqd = -1; + +static int g_bkup_nand_tid; +static int g_bkup_delay_tid; + +/** + * prototype declared + */ +static void BkupApilog(bkup_response_t *response, enum NvHalMedia current_media, + bkup_protocol_header_t *hdr, + bkup_query_result_t *query_result, char *buf, + uint32_t crc32, EFrameworkunifiedStatus ret_value); + +/** + * check status of file spicefied by path + */ +static int BkupCheckStatFromNv(enum NvHalMedia media, const char *path, + int check_size); + +/** + * rwlock unlock + */ +static inline void BkupRwlockUnlock(pthread_rwlock_t *rwlock, const char *path); + +/** + * rwlock read lock + */ +static inline void BkupRwlockRdlock(pthread_rwlock_t *rwlock, const char *path); + +/** + * rwlock write lock + */ +static inline void BkupRwlockWrlock(pthread_rwlock_t *rwlock, const char *path); + +/**\ingroup CheckNv + * \~english @par Brief + * Check the data stored on the storage device and check the data size. + * \~english @param [in] media + * enum NvHalMedia - Media type + * \~english @param [in] filename + * const char* - Concatenated string of "category name/item name" + * \~english @param [in] size + * uint32_t - Data size to be checked + * \~english @retval eFrameworkunifiedStatusOK OK + * \~english @retval eFrameworkunifiedStatusFileLoadError The file does not exist. + * \~english @retval eFrameworkunifiedStatusAccessError Check size failed + * \~english @retval eFrameworkunifiedStatusInvldParam Parameter error + * \~english @par Preconditons + * - none + * \~english @par Conditions of processing failure + * - If the media (media) specified in the parameter is smaller than NVHALMEDIA_CACHEDRAM or larger than NVHALMEDIA_NAND.\n + * [eFrameworkunifiedStatusInvldParam] + * - The identifier specified in the arguments is a NULL.[eFrameworkunifiedStatusInvldParam] + * - When the size specified in the arguments is 0.[eFrameworkunifiedStatusInvldParam] + * - Internal I/O handling errors (lstat).[eFrameworkunifiedStatusFileLoadError] + * - The size specified by the parameter does not correspond to the file size specified by the identifier.[eFrameworkunifiedStatusAccessError] + */ +static EFrameworkunifiedStatus CheckNv(enum NvHalMedia media, const char *filename, uint32_t size) { + uint32_t size_; + EFrameworkunifiedStatus ret; + ret = GetSizeNv(media, filename, &size_); // Get size + if (ret != eFrameworkunifiedStatusOK) { // If the GetSizeNv fails, the error is returned unchanged. + return ret; + } + if (size_ != size) { // Returns eFrameworkunifiedStatusAccessError if the sizes do not match. + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "invalid size:%d\n", size); + return eFrameworkunifiedStatusAccessError; + } + return eFrameworkunifiedStatusOK; // Returns eFrameworkunifiedStatusOK if size matches +} + + + +/** + * read file spicefied by id + * + * \retval 0 read success + * \retval -1 crc error + * \retval -2 read failed + * \retval -3 invalid param + */ +static int32_t BkupBufferReadFromNv(const enum NvHalMedia media, const char* path, + char *buf, size_t size, uint32_t *crc32) { + int32_t ret = 0; + EFrameworkunifiedStatus nv_ret = eFrameworkunifiedStatusFail; + const uint32_t size_all = static_cast<uint32_t>(size + sizeof(uint32_t)); + void* buffer = MAP_FAILED; + uint8_t* read_buffer = NULL; + uint32_t calc_crc32, get_crc32; + + if (path == NULL) { // LCOV_EXCL_BR_LINE 6:double check + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + return -1; // LCOV_EXCL_LINE 6:double check + } + + if (!buf) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "buf is NULL"); + return -1; + } + if ((buffer = BkupAnonMmap(size_all)) == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + // LCOV_EXCL_START 5:mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:map failed"); + ret = -1; + goto exit; + // LCOV_EXCL_STOP 5:mmap's error case. + } + + read_buffer = reinterpret_cast<uint8_t*>(buffer); + nv_ret = ReadNv(media, path, read_buffer, size_all); + if (nv_ret == eFrameworkunifiedStatusOK) { + const void* const src_buffer = reinterpret_cast<void *>(read_buffer + size); + void* dest_buffer = reinterpret_cast<void *>(&get_crc32); + memcpy(dest_buffer, src_buffer, sizeof(uint32_t)); + calc_crc32 = BkupCrc32(read_buffer, size); // LCOV_EXCL_BR_LINE 11:unexpected branch + if (get_crc32 != calc_crc32) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "invalid crc(%s):%#x:%#x", path, get_crc32, calc_crc32); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + ret = -1; + goto exit; + } + if (crc32 != NULL) { + *crc32 = get_crc32; + } + dest_buffer = reinterpret_cast<void *>(buf); + memcpy(dest_buffer, buffer, size); + } else if (nv_ret == eFrameworkunifiedStatusInvldParam) { // LCOV_EXCL_BR_LINE 6:double check + ret = -3; + } else { + ret = -2; + } +exit: + if (buffer != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + munmap(buffer, size_all); + } + + return ret; +} + +/* + * buffer -> file write + */ +static int32_t BkupBufferWriteToNv(const enum NvHalMedia media, const char* path, + char *buf, size_t size, uint32_t *crc32) { + if (buf == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "buf is NULL"); + return eFrameworkunifiedStatusNullPointer; + } + int32_t ret = 0; + EFrameworkunifiedStatus nv_ret = eFrameworkunifiedStatusFail; + const uint32_t size_all = static_cast<uint32_t>(size + sizeof(uint32_t)); + char *buffer = reinterpret_cast<char *>(MAP_FAILED); + uint32_t calc_crc32; + + if ((buffer = BkupAnonMmap(size_all)) == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + // LCOV_EXCL_START 5:mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:%s", strerror(errno)); + ret = -1; + goto exit; + // LCOV_EXCL_STOP 5:mmap's error case. + } + + calc_crc32 = BkupCrc32(buf, size); // LCOV_EXCL_BR_LINE 11:unexpected branch + if (crc32) { + *crc32 = calc_crc32; + } + + memcpy(buffer, buf, size); + memcpy(buffer + size, &calc_crc32, sizeof(uint32_t)); + + nv_ret = WriteNv(media, path, reinterpret_cast<uint8_t *>(buffer), size_all); + if (nv_ret != eFrameworkunifiedStatusOK) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "write to nv(%s):%s", path, strerror(ret)); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + ret = -1; + } + +exit: + if (buffer != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + munmap(buffer, size_all); + } + + return ret; +} + +/** + * inter media copy + */ +static int BkupMediaCopyFromNv(char *category_name, const char *item_name, + enum NvHalMedia src, enum NvHalMedia dst, + pthread_rwlock_t *src_rwlock, + pthread_rwlock_t *dst_rwlock) { + if (category_name == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "category_name is NULL"); + return eFrameworkunifiedStatusNullPointer; + } + + if (item_name == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "item_name is NULL"); + return eFrameworkunifiedStatusNullPointer; + } + int ret = -1; + uint32_t crc32; + char id_path[FILENAME_MAX] = {0}; + char *buffer = reinterpret_cast<char *>(MAP_FAILED); + + bkup_query_result_t query_result; + BkupParamGet(item_name, &query_result); // LCOV_EXCL_BR_LINE 11:unexpected branch + + char prefix_name[kBkupPrexixEncryptionSize + 1] = {0}; + if (query_result.encrypt != false) { + strncpy(prefix_name, kBkupPrexixEncryption, kBkupPrexixEncryptionSize); + } + snprintf(id_path, FILENAME_MAX, "%s/%s%s", category_name, prefix_name, item_name); + + if ((buffer = BkupAnonMmap(query_result.size)) == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + // LCOV_EXCL_START 5:mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:map failed"); + ret = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 5:mmap's error case. + } + + BkupRwlockRdlock(src_rwlock, id_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + if ((ret = BkupBufferReadFromNv(src, id_path, buffer, query_result.size, + &crc32)) >= 0) { + // LCOV_EXCL_BR_START 11:unexpected branch + BkupRwlockWrlock(dst_rwlock, id_path); + ret = BkupBufferWriteToNv(dst, id_path, buffer, query_result.size, &crc32); + BkupRwlockUnlock(dst_rwlock, id_path); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } + BkupRwlockUnlock(src_rwlock, id_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + +exit: + if (buffer != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + munmap(buffer, query_result.size); + } + + return ret; +} + +/** + * make backup path + */ +static int BkupMakeBkupPathToNvId(const char *category_name, + const char *item_name, char **path_buf, + int buf_size) { + int ret = -1; + char prefix_name[kBkupPrexixEncryptionSize + 1] = {0}; + + if ((*path_buf = BkupAnonMmap(buf_size)) == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + // LCOV_EXCL_START 5:mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:%s", strerror(errno)); + goto exit; + // LCOV_EXCL_STOP 5:mmap's error case. + } + bkup_query_result_t query_result; + if (BkupParamGet(item_name, &query_result) < 0) { // LCOV_EXCL_BR_LINE 6:Excluded due to checking by upper-level function + // LCOV_EXCL_START 6:Excluded due to checking by upper-level function + AGL_ASSERT_NOT_TESTED(); + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid item_name:%s", item_name); + goto exit; + // LCOV_EXCL_STOP 6:Excluded due to checking by upper-level function + } + if (query_result.encrypt != false) { + strncpy(prefix_name, kBkupPrexixEncryption, kBkupPrexixEncryptionSize); + } + snprintf(*path_buf, static_cast<size_t>(buf_size), "%s/%s%s", + category_name, prefix_name, item_name); + ret = 0; + +exit: + return ret; +} + +/** + * delete data + */ +static int BkupDeleteDataFromNv(const enum NvHalMedia media, const char* const path) { + int ret = 0; + EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK; + + if (path == NULL) { // LCOV_EXCL_BR_LINE 6:Excluded due to checking by upper-level function + // LCOV_EXCL_START 6:Excluded due to checking by upper-level function + AGL_ASSERT_NOT_TESTED(); + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "path is NULL"); + ret = -1; + return ret; + // LCOV_EXCL_STOP 6:Excluded due to checking by upper-level function + } + const size_t path_size = static_cast<size_t>(std::string(path).length()); + if (path_size > FILENAME_MAX) { // LCOV_EXCL_BR_LINE 6:Excluded due to checking by upper-level function + // LCOV_EXCL_START 6:Excluded due to checking by upper-level function + AGL_ASSERT_NOT_TESTED(); + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "path size error"); + ret = -1; + return ret; + // LCOV_EXCL_STOP 6:Excluded due to checking by upper-level function + } + + uint32_t size = 0; + e_status = GetSizeNv(media, path, &size); + if (e_status == eFrameworkunifiedStatusFileLoadError) { + // If the file does not exist, deleet it successfully + return ret; + } else if (e_status != eFrameworkunifiedStatusOK) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "GetSizeNv e_status:%d\n", e_status); + ret = -1; + return ret; + } else { + // no proc + } + + e_status = DeleteNv(media, path); + if (e_status != eFrameworkunifiedStatusOK) { + ret = -1; + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "DeleteNv e_status:%d\n", e_status); + } + return ret; +} + +/** + * get rwlock + */ +static pthread_rwlock_t *BkupGetRwlock(const char *item_name, + enum NvHalMedia media, + bkup_query_result_t *query_result) { + int ret; + pthread_rwlock_t *rwlock, *org_rwlock; + pthread_rwlockattr_t attr; + + if (query_result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "query_result is NULL"); + return NULL; + } + + if (media != NVHALMEDIA_BACKUPDRAM || query_result->backup_dram == false || query_result->nand == false) { + return NULL; + } + // backupDram && nand + if (query_result->opt != NULL) { + return reinterpret_cast<pthread_rwlock_t *>(query_result->opt); + } + + if ((ret = pthread_rwlockattr_init(&attr)) != 0) { // LCOV_EXCL_BR_LINE 5:pthread_rwlockattr_init's error case. + // LCOV_EXCL_START 5:pthread_rwlockattr_init's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_rwlockattr_init:%s", strerror(ret)); + return NULL; + // LCOV_EXCL_STOP 5:pthread_rwlockattr_init's error case. + } + + // LCOV_EXCL_BR_START 5:pthread_rwlockattr_setkind_np's error case. + if ((ret = pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)) != 0) { + // LCOV_EXCL_BR_STOP 5:pthread_rwlockattr_setkind_np's error case. + // LCOV_EXCL_START 5:pthread_rwlockattr_setkind_np's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_rwlockattr_setkind_np:%s", strerror(ret)); + return NULL; + // LCOV_EXCL_STOP 5:pthread_rwlockattr_setkind_np's error case. + } + + // LCOV_EXCL_BR_START 5:malloc's error case. + if ((rwlock = reinterpret_cast<pthread_rwlock_t *>(malloc(sizeof(pthread_rwlock_t)))) == NULL) { + // LCOV_EXCL_BR_STOP 5:malloc's error case. + // LCOV_EXCL_START 5:malloc's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "malloc failed"); + return NULL; + // LCOV_EXCL_STOP 5:malloc's error case. + } + + if ((ret = pthread_rwlock_init(rwlock, &attr)) != 0) { // LCOV_EXCL_BR_LINE 5:pthread_rwlock_init's error case. + // LCOV_EXCL_START 5:pthread_rwlock_init's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_rwlock_init:%s", strerror(ret)); + free(rwlock); + return NULL; + // LCOV_EXCL_STOP 5:pthread_rwlock_init's error case. + } + + // LCOV_EXCL_BR_START 11:unexpected branch + org_rwlock = reinterpret_cast<pthread_rwlock_t *>(BkupParamSetOpt(item_name, rwlock)); + // LCOV_EXCL_BR_STOP 11:unexpected branch + if (org_rwlock == reinterpret_cast<void *>(-1)) { // LCOV_EXCL_BR_LINE 6:org_rwlock will not be -1 + // LCOV_EXCL_START 6:org_rwlock will not be -1 + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid item_name:%s", item_name != 0 ? item_name : NULL); + free(rwlock); + return NULL; + // LCOV_EXCL_STOP 6:org_rwlock will not be -1 + } else if (org_rwlock != NULL) { // LCOV_EXCL_BR_LINE 5:gcc builtin function's error case + // conflict + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + free(rwlock); // LCOV_EXCL_LINE 5:gcc builtin function's error case + rwlock = org_rwlock; // LCOV_EXCL_LINE 5:gcc builtin function's error case + } + + query_result->opt = rwlock; + return rwlock; +} + +/** + * rwlock read lock + */ +static inline void BkupRwlockRdlock(pthread_rwlock_t *rwlock, const char *path) { + if (rwlock) { + int ret; + if ((ret = pthread_rwlock_rdlock(rwlock)) != 0) { // LCOV_EXCL_BR_LINE 5:pthread_rwlock_rdlock's error case. + // LCOV_EXCL_START 5:pthread_rwlock_rdlock's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_rwlock_rdlock(%s):%s", path, strerror(ret)); + // LCOV_EXCL_STOP 5:pthread_rwlock_rdlock's error case. + } + } +} + +/** + * rwlock write lock + */ +static inline void BkupRwlockWrlock(pthread_rwlock_t *rwlock, const char *path) { + if (rwlock) { + int ret; + if ((ret = pthread_rwlock_wrlock(rwlock)) != 0) { // LCOV_EXCL_BR_LINE 5:pthread_rwlock_wrlock's error case. + // LCOV_EXCL_START 5:pthread_rwlock_wrlock's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_rwlock_wrlock(%s):%s", path, strerror(ret)); + // LCOV_EXCL_STOP 5:pthread_rwlock_wrlock's error case. + } + } +} + +/** + * rwlock unlock + */ +static inline void BkupRwlockUnlock(pthread_rwlock_t *rwlock, const char *path) { + if (rwlock) { + int ret; + if ((ret = pthread_rwlock_unlock(rwlock)) != 0) { // LCOV_EXCL_BR_LINE 5:pthread_rwlock_unlock's error case. + // LCOV_EXCL_START 5:pthread_rwlock_unlock's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "pthread_rwlock_unlock(%s):%s", path, strerror(ret)); + // LCOV_EXCL_STOP 5:pthread_rwlock_unlock's error case. + } + } +} + +/** + * inter thread communication MQ open + */ +static mqd_t BkupItcMqopen(const char *mq_name, int flags) { + struct mq_attr attr; + + if (mq_name == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "mq_name is NULL"); + return -1; + } + + attr.mq_flags = 0; + attr.mq_maxmsg = 256; + attr.mq_msgsize = sizeof(bkup_itc_message_t); + + return mq_open(mq_name, flags, 0660, &attr); +} + +/** + * write & rename + */ +static int BkupWriteRename(const char *category_name, const char *item_name, + enum NvHalMedia media, char *buf, int size, + pthread_rwlock_t *rwlock) { + int ret = -1; + char *full_path = reinterpret_cast<char *>(MAP_FAILED); + + // LCOV_EXCL_BR_START 5:mmap's error case. + if (BkupMakeBkupPathToNvId(category_name, item_name, &full_path, FILENAME_MAX) < 0) { + // LCOV_EXCL_BR_STOP 5:mmap's error case. + // LCOV_EXCL_START 5:mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + goto exit; + // LCOV_EXCL_STOP 5:mmap's error case. + } + + BkupRwlockWrlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + if (BkupBufferWriteToNv(media, full_path, buf, size, NULL) < 0) { + BkupRwlockUnlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + goto exit; + } + BkupRwlockUnlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + + ret = size; + +exit: + if (full_path != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + munmap(full_path, FILENAME_MAX); + } + return ret; +} + +/** + * stat check + * + * \retval 0 file exists + * \retval -1 file not exists + * \retval -2 size error + */ +static int BkupCheckStatFromNv(enum NvHalMedia media, const char *path, + int check_size) { + uint32_t size = check_size + static_cast<uint32_t>(sizeof(uint32_t)); + const EFrameworkunifiedStatus ret = CheckNv(media, path, size); + + if (path == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "path is NULL"); + return -1; + } + + if (eFrameworkunifiedStatusOK == ret) { + return 0; + } else if (eFrameworkunifiedStatusAccessError == ret) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "CheckNv e_status:%d", ret); + return -2; + } else { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "CheckNv e_status:%d", ret); + return -1; + } +} + +/** + * media stat + */ +static int BkupMediaStat(const char *category_name, const char *item_name, enum NvHalMedia src, int size) { + int ret = -1; + char *path = reinterpret_cast<char *>(MAP_FAILED); + + // LCOV_EXCL_BR_START 5:mmap's error case. + if (BkupMakeBkupPathToNvId(category_name, item_name, &path, FILENAME_MAX) < 0) { + // LCOV_EXCL_BR_STOP 5:mmap's error case. + // LCOV_EXCL_START 5:mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + goto exit; + // LCOV_EXCL_STOP 5:mmap's error case. + } + ret = BkupCheckStatFromNv(src, path, size); // LCOV_EXCL_BR_LINE 11:unexpected branch + +exit: + if (path != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + munmap(path, FILENAME_MAX); + } + return ret; +} + +/** + * stat check & read + * + * \retval 0 file exists + * \retval -1 file not exists + */ +static int BkupCheckStatRead(enum NvHalMedia current_media, const char *path, + char *buf, int check_size, uint32_t *crc32, + pthread_rwlock_t *rwlock) { + int ret; + + if ((ret = BkupCheckStatFromNv(current_media, path, check_size)) < 0) { + return ret; + } + + BkupRwlockRdlock(rwlock, path); + + if (BkupBufferReadFromNv(current_media, path, buf, check_size, crc32) < 0) { + BkupRwlockUnlock(rwlock, path); + return -1; + } + + BkupRwlockUnlock(rwlock, path); + return 0; +} + +/** + * valid check + * + * \retval 0 file invalid & do nothing + * \retval -1 file invalid but create 0 fill file + * \retval 1 file valid + */ +static int BkupCheckRead(const char *path, enum NvHalMedia current_media, + bkup_protocol_command_t command, char *rcv_buf, + char *read_buf, uint32_t *crc32, + bkup_query_result_t *query_result, + pthread_rwlock_t *rwlock) { + int ret = -1; + + if (rcv_buf == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "rcv_buf is NULL"); + return 0; + } + if (query_result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "query_result is NULL"); + return 0; + } + + bkup_protocol_header_t *hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + + if (BkupCheckStatRead(current_media, path, read_buf, query_result->size, crc32, rwlock) < 0) { + // file not exists + if (current_media == NVHALMEDIA_NAND || query_result->nand == false) { + goto exit; + } else { + if (command == BKUP_CMD_READ) { + /* + * Read + */ + if (BkupCheckStatFromNv(NVHALMEDIA_NAND, path, query_result->size) == 0) { + // do nothing + ret = 0; + } else { + // take preference BackupDRAM or CacheDRAM + ret = -1; + } + } else { + /* + * Write/Fill + */ + pthread_rwlock_t *nand_rwlock = BkupGetRwlock(hdr->item_name, NVHALMEDIA_NAND, query_result); + if (BkupCheckStatRead(NVHALMEDIA_NAND, path, read_buf, query_result->size, NULL, nand_rwlock) == 0) { + // write back cache + if (BkupWriteRename(query_result->category_name, hdr->item_name, + current_media, read_buf, query_result->size, + rwlock) >= 0) { + ret = 1; + } else { + // copy error, do nothing + ret = 0; + } + } else { + // take preference BackupDRAM or CacheDRAM + ret = -1; + } + } + goto exit; + } + } + ret = 1; +exit: + return ret; +} + +/** + * read command + */ +static int BkupCmdRead(bkup_response_t *response, enum NvHalMedia current_media, + char *rcv_buf, bkup_query_result_t *query_result) { + int ret = -1; + if (response == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "response is NULL"); + return -1; + } + if (rcv_buf == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "rcv_buf is NULL"); + return -1; + } + if (query_result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "query_result is NULL"); + return -1; + } + bkup_protocol_header_t *hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + // LCOV_EXCL_BR_START 11:unexpected branch + pthread_rwlock_t *rwlock = BkupGetRwlock(hdr->item_name, current_media, query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + char *full_path = reinterpret_cast<char *>(MAP_FAILED); + char *buf = reinterpret_cast<char *>(MAP_FAILED); + size_t buf_size = 0; + uint32_t crc32 = 0; + EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK; + + // LCOV_EXCL_BR_START 5:mmap's error case. + if (BkupMakeBkupPathToNvId(query_result->category_name, hdr->item_name, &full_path, FILENAME_MAX) < 0) { + // LCOV_EXCL_BR_STOP 5:mmap's error case. + // LCOV_EXCL_START 5:mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + e_status = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 5:mmap's error case. + } + + if ((buf = BkupAnonMmap(query_result->size)) == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case. + // LCOV_EXCL_START 5:mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:%s", strerror(errno)); + e_status = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 5:mmap's error case. + } + buf_size = query_result->size; + + ret = BkupCheckRead(full_path, current_media, hdr->command, rcv_buf, buf, + &crc32, query_result, rwlock); // LCOV_EXCL_BR_LINE 11:unexpected branch + if (ret == -1) { + // return all 0 + ret = hdr->size; + goto exit; + } else if (ret == 0) { + // do nothing + goto exit; + } + + // success + ret = hdr->size; + + // caching to memory + if (current_media == NVHALMEDIA_NAND) { + if (query_result->cache_dram) { + if (BkupMediaStat(query_result->category_name, hdr->item_name, + NVHALMEDIA_CACHEDRAM, query_result->size) < 0) { + // LCOV_EXCL_BR_START 11:unexpected branch + pthread_rwlock_t *dst_rwlock = + BkupGetRwlock(hdr->item_name, NVHALMEDIA_CACHEDRAM, query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + BkupWriteRename(query_result->category_name, hdr->item_name, + NVHALMEDIA_CACHEDRAM, buf, query_result->size, + dst_rwlock); // LCOV_EXCL_BR_LINE 11:unexpected branch + } + } + if (query_result->backup_dram) { + if (BkupMediaStat(query_result->category_name, hdr->item_name, + NVHALMEDIA_BACKUPDRAM, query_result->size) < 0) { + // LCOV_EXCL_BR_START 11:unexpected branch + pthread_rwlock_t *dst_rwlock = + BkupGetRwlock(hdr->item_name, NVHALMEDIA_BACKUPDRAM, query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + BkupWriteRename(query_result->category_name, hdr->item_name, + NVHALMEDIA_BACKUPDRAM, buf, query_result->size, + dst_rwlock); // LCOV_EXCL_BR_LINE 11:unexpected branch + } + } + } + +exit: + if (ret != 0 && buf != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + // LCOV_EXCL_BR_START 11:unexpected branch + BkupApilog(response, current_media, hdr, query_result, buf, crc32, e_status); + // LCOV_EXCL_BR_STOP 11:unexpected branch + // LCOV_EXCL_BR_START 4: NSFW error case + if ((*response->set_response)(response->opt, buf + hdr->offset, hdr->size, e_status) < 0) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + ret = -1; // LCOV_EXCL_LINE 4: NSFW error case + } + } + + if (full_path != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + munmap(full_path, FILENAME_MAX); + } + if (buf != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + munmap(buf, buf_size); + } + return ret; +} + +/** + * write command + */ +static int BkupCmdWrite(bkup_response_t *response, + enum NvHalMedia current_media, char *rcv_buf, + bkup_query_result_t *query_result) { + int ret = -1; + + if (response == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "response is NULL"); + return -1; + } + if (rcv_buf == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "rcv_buf is NULL"); + return -1; + } + if (query_result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "query_result is NULL"); + return -1; + } + bkup_protocol_header_t *hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + // LCOV_EXCL_BR_START 11:unexpected branch + pthread_rwlock_t *rwlock = BkupGetRwlock(hdr->item_name, current_media, query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + char *full_path = reinterpret_cast<char *>(MAP_FAILED); + char *buf = reinterpret_cast<char *>(MAP_FAILED); + char *header = NULL; + uint32_t crc32 = 0; + int buf_size = 0; + + // LCOV_EXCL_BR_START 5: mmap's error case. + if (BkupMakeBkupPathToNvId(query_result->category_name, hdr->item_name, &full_path, FILENAME_MAX) < 0) { + // LCOV_EXCL_BR_STOP 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + goto exit; // LCOV_EXCL_LINE 5: mmap's error case. + } + + if (hdr->offset != 0 || hdr->size != (uint32_t)query_result->size) { + /* + * partial write + */ + if ((buf = BkupAnonMmap(query_result->size)) == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + // LCOV_EXCL_START 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:%s", strerror(errno)); + goto exit; + // LCOV_EXCL_STOP 5: mmap's error case. + } + buf_size = query_result->size; + + // LCOV_EXCL_BR_START 11:unexpected branch + ret = BkupCheckRead(full_path, current_media, hdr->command, rcv_buf, buf, NULL, query_result, rwlock); + // LCOV_EXCL_BR_STOP 11:unexpected branch + if (ret == 0) { + // do nothing + goto exit; + } + + header = buf; + memcpy(buf + hdr->offset, rcv_buf + sizeof(bkup_protocol_header_t), hdr->size); + BkupRwlockWrlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + if (BkupBufferWriteToNv(current_media, full_path, buf, query_result->size, &crc32) < 0) { + BkupRwlockUnlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + goto exit; + } + BkupRwlockUnlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + } else { + /* + * whole write + */ + header = rcv_buf + sizeof(bkup_protocol_header_t); + BkupRwlockWrlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + if (BkupBufferWriteToNv(current_media, full_path, + rcv_buf + sizeof(bkup_protocol_header_t), hdr->size, &crc32) < 0) { + BkupRwlockUnlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + goto exit; + } + BkupRwlockUnlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + } + + // success + ret = hdr->size; + +exit: + EFrameworkunifiedStatus e_status = ret < 0 ? eFrameworkunifiedStatusFail : eFrameworkunifiedStatusOK; + if (current_media == NVHALMEDIA_NAND) { + if (query_result->cache_dram == false && query_result->backup_dram == false) { + // LCOV_EXCL_BR_START 11:unexpected branch + BkupApilog(response, current_media, hdr, query_result, header, crc32, e_status); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } + if ((*response->set_response)(response->opt, NULL, 0, e_status) < 0) { // LCOV_EXCL_BR_LINE 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + ret = -1; // LCOV_EXCL_LINE 4: NSFW error case + } + } else { + // LCOV_EXCL_BR_START 11:unexpected branch + BkupApilog(response, current_media, hdr, query_result, header, crc32, e_status); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } + + if (buf != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + munmap(buf, buf_size); + } + if (full_path != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + munmap(full_path, FILENAME_MAX); + } + return ret; +} + +/** + * fill command + */ +static int BkupCmdFill(bkup_response_t *response, enum NvHalMedia current_media, + char *rcv_buf, bkup_query_result_t *query_result) { + int ret = -1; + bkup_protocol_header_t *hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + // LCOV_EXCL_BR_START 11:unexpected branch + pthread_rwlock_t *rwlock = BkupGetRwlock(hdr->item_name, current_media, query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + char *full_path = reinterpret_cast<char *>(MAP_FAILED); + char *buf = reinterpret_cast<char *>(MAP_FAILED); + uint32_t crc32 = 0; + + if (response == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "response is NULL"); + return -1; + } + if (rcv_buf == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "rcv_buf is NULL"); + return -1; + } + if (query_result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "query_result is NULL"); + return -1; + } + // LCOV_EXCL_BR_START 5: mmap's error case. + if (BkupMakeBkupPathToNvId(query_result->category_name, hdr->item_name, &full_path, FILENAME_MAX) < 0) { + // LCOV_EXCL_BR_STOP 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + goto exit; // LCOV_EXCL_LINE 5: mmap's error case. + } + + // LCOV_EXCL_BR_START 5: mmap's error case. + if ((buf = BkupAnonMmap(query_result->size)) == MAP_FAILED) { + // LCOV_EXCL_BR_STOP 5: mmap's error case. + // LCOV_EXCL_START 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:%s", strerror(errno)); + goto exit; + // LCOV_EXCL_STOP 5: mmap's error case. + } + + if (hdr->offset != 0 || hdr->size != (uint32_t)query_result->size) { + /* + * partial fill + */ + // LCOV_EXCL_BR_START 11:unexpected branch + ret = BkupCheckRead(full_path, current_media, hdr->command, rcv_buf, buf, NULL, query_result, rwlock); + // LCOV_EXCL_BR_STOP 11:unexpected branch + if (ret == 0) { + // do nothing + goto exit; + } + } + + memset(buf + hdr->offset, hdr->fill_patern, hdr->size); + BkupRwlockWrlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + if (BkupBufferWriteToNv(current_media, full_path, buf, query_result->size, &crc32) < 0) { + BkupRwlockUnlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + goto exit; + } + BkupRwlockUnlock(rwlock, full_path); // LCOV_EXCL_BR_LINE 11:unexpected branch + + // success + ret = hdr->size; + +exit: + EFrameworkunifiedStatus e_status = ret < 0 ? eFrameworkunifiedStatusFail : eFrameworkunifiedStatusOK; + if (current_media == NVHALMEDIA_NAND) { + if (query_result->cache_dram == false && query_result->backup_dram == false) { + // LCOV_EXCL_BR_START 11:unexpected branch + BkupApilog(response, current_media, hdr, query_result, buf, crc32, e_status); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } + if ((*response->set_response)(response->opt, NULL, 0, e_status) < 0) { // LCOV_EXCL_BR_LINE 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + ret = -1; // LCOV_EXCL_LINE 4: NSFW error case + } + } else { + // LCOV_EXCL_BR_START 11:unexpected branch + BkupApilog(response, current_media, hdr, query_result, buf, crc32, e_status); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } + + if (buf != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + munmap(buf, query_result->size); + } + if (full_path != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + munmap(full_path, FILENAME_MAX); + } + return ret; +} + +/** + * copy command + */ +static int BkupCmdCopy(bkup_response_t *response, enum NvHalMedia current_media, + char *rcv_buf, bkup_query_result_t *query_result) { + if (rcv_buf == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "rcv_buf is NULL"); + return -1; + } + if (query_result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "query_result is NULL"); + return -1; + } + bkup_protocol_header_t *hdr = + reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + pthread_rwlock_t *src_rwlock = + BkupGetRwlock(hdr->item_name, hdr->src_media, query_result); + pthread_rwlock_t *dst_rwlock = + BkupGetRwlock(hdr->item_name, current_media, query_result); + + int ret = BkupMediaCopyFromNv(query_result->category_name, hdr->item_name, hdr->src_media, current_media, src_rwlock, + dst_rwlock); + + if (response == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "response is NULL"); + return -1; + } + + if (current_media == NVHALMEDIA_NAND) { + // LCOV_EXCL_BR_START 4: NSFW error case + if ((*response->set_response)(response->opt, NULL, 0, ret < 0 ? eFrameworkunifiedStatusFail : eFrameworkunifiedStatusOK) < 0) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + ret = -1; // LCOV_EXCL_LINE 4: NSFW error case + } + } + return ret; +} + +/** + * check command + */ +static int BkupCmdCheck(bkup_response_t *response, + enum NvHalMedia current_media, char *rcv_buf, + bkup_query_result_t *query_result) { + int ret = 0; + bkup_protocol_header_t *hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + char *full_path = reinterpret_cast<char *>(MAP_FAILED); + + if (rcv_buf == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "rcv_buf is NULL"); + return -1; + } + if (query_result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "query_result is NULL"); + return -1; + } + // LCOV_EXCL_BR_START 5: mmap's error case. + if (BkupMakeBkupPathToNvId(query_result->category_name, hdr->item_name, &full_path, FILENAME_MAX) < 0) { + // LCOV_EXCL_BR_STOP 5: mmap's error case. + // LCOV_EXCL_START 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + ret = -3; + goto exit; + // LCOV_EXCL_STOP 5: mmap's error case. + } + ret = BkupCheckStatFromNv(current_media, full_path, query_result->size); // LCOV_EXCL_BR_LINE 11:unexpected branch + +exit: + if (full_path != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + munmap(full_path, FILENAME_MAX); + } + return ret; +} + +/** + * delete command + */ +static int BkupCmdDeleteData(bkup_response_t* const response, + const enum NvHalMedia current_media, + char* const rcv_buf, + bkup_query_result_t* const query_result) { + int ret = -1; + char *full_path = NULL; + bkup_protocol_header_t* hdr = reinterpret_cast<bkup_protocol_header_t*>(NULL); + pthread_rwlock_t* rwlock = reinterpret_cast<pthread_rwlock_t*>(NULL); + if ((response == NULL) || (rcv_buf == NULL) || (query_result == NULL)) { // LCOV_EXCL_BR_LINE 6:Excluded as no NULL is currently passed + // LCOV_EXCL_START 6:Excluded as no NULL is currently passed + AGL_ASSERT_NOT_TESTED(); + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Resp or Buf or Query is NULL"); + goto exit; + // LCOV_EXCL_STOP 6:Excluded as no NULL is currently passed + } + hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + rwlock = BkupGetRwlock(hdr->item_name, current_media, query_result); + if (BkupMakeBkupPathToNvId(query_result->category_name, hdr->item_name, &full_path, FILENAME_MAX) < 0) { // LCOV_EXCL_BR_LINE 6:Excluded due to checking by upper-level function + // LCOV_EXCL_START 6:Excluded due to checking by upper-level function + AGL_ASSERT_NOT_TESTED(); + goto exit; + // LCOV_EXCL_STOP 6:Excluded due to checking by upper-level function + } + BkupRwlockWrlock(rwlock, full_path); + ret = BkupDeleteDataFromNv(current_media, full_path); + if (ret != 0) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "BkupDeleteDataFromNv Error"); + } + BkupRwlockUnlock(rwlock, full_path); + +exit: + if ((response != NULL) && (query_result != NULL) && (hdr != NULL)) { // LCOV_EXCL_BR_LINE 6:Excluded as no NULL is currently passed + EFrameworkunifiedStatus e_status = (ret < 0) ? eFrameworkunifiedStatusFail : eFrameworkunifiedStatusOK; + if (current_media == NVHALMEDIA_NAND) { + if ((query_result->cache_dram == false) && (query_result->backup_dram == false)) { + BkupApilog(response, current_media, hdr, query_result, NULL, 0, e_status); + } + if ((*response->set_response)(response->opt, NULL, 0, e_status) < 0) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Response Error"); + ret = -1; + } + } else { + BkupApilog(response, current_media, hdr, query_result, NULL, 0, e_status); + } + } + + if (full_path != NULL) { // LCOV_EXCL_BR_LINE 6:Excluded because checked by BkupMakeBkupPathToNvId() + munmap(full_path, FILENAME_MAX); + } + return ret; +} + +/** + * common file handler + */ +static int BkupHandlerFile(bkup_response_t *response, + enum NvHalMedia current_media, char *rcv_buf, + bkup_query_result_t *query_result) { + int ret = 0; + bkup_protocol_header_t *hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + + if (rcv_buf == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "rcv_buf is NULL"); + return -1; + } + + switch (hdr->command) { // LCOV_EXCL_BR_LINE 6:double check + case BKUP_CMD_READ: + ret = BkupCmdRead(response, current_media, rcv_buf, query_result); + break; + + case BKUP_CMD_WRITE: + ret = BkupCmdWrite(response, current_media, rcv_buf, query_result); + break; + + case BKUP_CMD_FILL: + ret = BkupCmdFill(response, current_media, rcv_buf, query_result); + break; + + case BKUP_CMD_COPY_INNER: + ret = BkupCmdCopy(response, current_media, rcv_buf, query_result); + break; + + case BKUP_CMD_DELETE: + ret = BkupCmdDeleteData(response, current_media, rcv_buf, query_result); + break; + + default: + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + break; // LCOV_EXCL_LINE 6:double check + } + return ret; +} + +/** + * Main's response + */ +static int BkupSetResponseNsfw(void *opt, void *buf, int size, EFrameworkunifiedStatus ret_value) { + EFrameworkunifiedStatus e_status; + + if (buf != NULL) { // LCOV_EXCL_BR_LINE 6:double check + // LCOV_EXCL_BR_START 4: NSFW error case + if ((e_status = FrameworkunifiedSetSyncResponseData((HANDLE)opt, buf, size)) != eFrameworkunifiedStatusOK) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + // LCOV_EXCL_START 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedSetSyncResponseData:%d", e_status); + return -1; + // LCOV_EXCL_STOP 4: NSFW error case + } + } + return 0; +} + +/** + * write apilog + */ +static void BkupApilog(bkup_response_t *response, enum NvHalMedia current_media, + bkup_protocol_header_t *hdr, + bkup_query_result_t *query_result, char *buf, + uint32_t crc32, EFrameworkunifiedStatus ret_value) { + const char *src; + const char *cmd; + char header[12] = "-- -- -- --"; + const char c[] = "0123456789abcdef"; + + if (response == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "response is NULL"); + return; + } + if (hdr == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "hdr is NULL"); + return; + } + if (query_result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "query_result is NULL"); + return; + } + if (response->set_response == BkupSetResponseNsfw) { + src = FrameworkunifiedGetMsgSrc((HANDLE)response->opt); // LCOV_EXCL_BR_LINE 11:unexpected branch + } else { + // LCOV_EXCL_BR_START 11:unexpected branch + src = (reinterpret_cast<bkup_itc_message_t *>(response->opt))->nand.client_name; + // LCOV_EXCL_BR_STOP 11:unexpected branch + } + + switch (hdr->command) { // LCOV_EXCL_BR_LINE 6:double check + case BKUP_CMD_READ: + cmd = "RD"; + break; + case BKUP_CMD_WRITE: + cmd = "WR"; + break; + case BKUP_CMD_FILL: + cmd = "FILL"; + break; + case BKUP_CMD_READ_NUM: + // LCOV_EXCL_START 6:double check + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + cmd = "RDN"; + break; + // LCOV_EXCL_STOP 6:double check + case BKUP_CMD_SIZE_NUM: + // LCOV_EXCL_START 6:double check + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + cmd = "SZN"; + break; + // LCOV_EXCL_STOP 6:double check + case BKUP_CMD_DELETE: + cmd = "DEL"; + break; + default: + // LCOV_EXCL_START 6:double check + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + cmd = "UNKNOWN"; + break; + // LCOV_EXCL_STOP 6:double check + } + + if (buf) { // LCOV_EXCL_BR_LINE 6:double check + int i; + for (i = 0; i < 4; i++) { + if (query_result->size > i) { + header[i * 3] = c[*(buf + i) >> 4]; + header[i * 3 + 1] = c[*(buf + i) & 0xf]; + } + } + } + + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ALSA, "", "%s/%s/%s/o:%d/s:%d/h:%s/c:%x/r:%d", src, cmd, hdr->item_name, hdr->offset, hdr->size, + header, crc32, ret_value); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" +} + +/** + * Tweak command + */ +static int BkupTweakCommand(enum NvHalMedia current_media, char **rcv_buf, + int *rcv_size, bkup_query_result_t *query_result) { + int ret = -1; + bkup_protocol_header_t update_hdr; + bkup_protocol_header_t *hdr = reinterpret_cast<bkup_protocol_header_t *>(*rcv_buf); + + if (current_media == NVHALMEDIA_NAND) { // LCOV_EXCL_BR_LINE 6:current_media never will be NVHALMEDIA_NAND + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + ret = 0; // LCOV_EXCL_LINE 6:current_media never will be NVHALMEDIA_NAND + goto exit; // LCOV_EXCL_LINE 6:current_media never will be NVHALMEDIA_NAND + } + if (rcv_size == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "rcv_size is NULL"); + return -1; + } + if (query_result == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "query_resul is NULL"); + return -1; + } + + if ((hdr->command == BKUP_CMD_WRITE || hdr->command == BKUP_CMD_FILL) && + (hdr->offset != 0 || hdr->size != (uint32_t)query_result->size)) { + // partial request + if ((current_media == NVHALMEDIA_CACHEDRAM && + (query_result->nand || query_result->backup_dram)) || + (current_media == NVHALMEDIA_BACKUPDRAM && query_result->nand)) { + memset(&update_hdr, 0, sizeof(update_hdr)); + BkupStrlcpy(update_hdr.item_name, hdr->item_name, sizeof(update_hdr.item_name)); + update_hdr.command = BKUP_CMD_COPY_INNER; + update_hdr.src_media = current_media; + munmap(*rcv_buf, *rcv_size); + *rcv_size = 0; + // LCOV_EXCL_BR_START 5: mmap's error case. + if ((*rcv_buf = BkupAnonMmap(sizeof(bkup_protocol_header_t))) == MAP_FAILED) { + // LCOV_EXCL_BR_STOP 5: mmap's error case. + // LCOV_EXCL_START 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:%s", strerror(errno)); + goto exit; + // LCOV_EXCL_STOP 5: mmap's error case. + } + *rcv_size = sizeof(bkup_protocol_header_t); + memcpy(*rcv_buf, &update_hdr, sizeof(update_hdr)); + } + } + ret = 0; + +exit: + return ret; +} + +/** + * Main callback handler + */ +EFrameworkunifiedStatus BkupHandler(HANDLE h_app) { + EFrameworkunifiedStatus e_status = eFrameworkunifiedStatusOK; + uint32_t rcv_size = 0; + char *rcv_buf = NULL; + bkup_protocol_header_t *hdr; + bkup_query_result_t query_result; + bool hold_rcv_buf = false; + int ret = 0; + bkup_response_t response_nsfw = {BkupSetResponseNsfw, h_app}; + + if ((rcv_size = FrameworkunifiedGetMsgLength(h_app)) < sizeof(bkup_protocol_header_t)) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedGetMsgLength: size fail:%d", rcv_size); + e_status = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 4: NSFW error case. + } + + rcv_buf = reinterpret_cast<char *>(mmap(NULL, rcv_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0)); + if (rcv_buf == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + // LCOV_EXCL_START 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + rcv_size = 0; + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:%s", strerror(errno)); + e_status = eFrameworkunifiedStatusInvldParam; + goto exit; + // LCOV_EXCL_STOP 5: mmap's error case. + } + + // LCOV_EXCL_BR_START 4: NSFW error case. + if ((e_status = FrameworkunifiedGetMsgDataOfSize(h_app, rcv_buf, rcv_size, eSMRRelease)) != eFrameworkunifiedStatusOK) { + // LCOV_EXCL_BR_STOP 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedGetMsgDataOfSize:%d", e_status); + goto exit; + // LCOV_EXCL_STOP 4: NSFW error case. + } + + hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + if (hdr->command < 0 || hdr->command >= BKUP_CMD_MAX) { // LCOV_EXCL_BR_LINE 6:double check + // LCOV_EXCL_START 6:double check + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid command:%d", hdr->command); + e_status = eFrameworkunifiedStatusInvldParam; + goto exit; + // LCOV_EXCL_STOP 6:double check + } + + if (hdr->command == BKUP_CMD_READ_NUM || hdr->command == BKUP_CMD_SIZE_NUM) { + // LCOV_EXCL_BR_START 11:unexpected branch + if (BkupParamGetNumid(hdr->num_id, &query_result, hdr->item_name, sizeof(hdr->item_name)) < 0) { + // LCOV_EXCL_BR_STOP 11:unexpected branch + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid num_id:%d", hdr->num_id); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + e_status = eFrameworkunifiedStatusInvldParam; + goto exit; + } + + if (hdr->command == BKUP_CMD_READ_NUM) { + hdr->command = BKUP_CMD_READ; + } + } else { + if (BkupParamGet(hdr->item_name, &query_result) < 0) { // LCOV_EXCL_BR_LINE 11:unexpected branch + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid item_name:%s", hdr->item_name != 0 ? hdr->item_name : NULL); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + e_status = eFrameworkunifiedStatusInvldParam; + goto exit; + } + } + + if (hdr->command == BKUP_CMD_READ || hdr->command == BKUP_CMD_WRITE || hdr->command == BKUP_CMD_FILL) { + if (hdr->size == 0) { + // do nothing + goto exit; + } + if (hdr->size + hdr->offset > (uint32_t)query_result.size) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid size+offset:%d+%d", hdr->size, hdr->offset); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + e_status = eFrameworkunifiedStatusInvldParam; + goto exit; + } + } + + // LCOV_EXCL_BR_START 6: g_bkup_internal_state will not be BKUP_STATE_INIT + if (g_bkup_internal_state == BKUP_STATE_INIT) { + // LCOV_EXCL_BR_STOP 6: g_bkup_internal_state will not be BKUP_STATE_INIT + // LCOV_EXCL_START 6: same as above + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + e_status = eFrameworkunifiedStatusErrOther; + goto exit; + // LCOV_EXCL_STOP 6: same as above + } + // LCOV_EXCL_BR_START 6: g_bkup_internal_state will not be BKUP_STATE_TERM + if (g_bkup_internal_state == BKUP_STATE_TERM) { + // LCOV_EXCL_BR_STOP 6: g_bkup_internal_state will not be BKUP_STATE_TERM + // LCOV_EXCL_START 6: same as above + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + e_status = eFrameworkunifiedStatusExit; + goto exit; + // LCOV_EXCL_STOP 6: same as above + } + + if (hdr->command == BKUP_CMD_SIZE || hdr->command == BKUP_CMD_SIZE_NUM) { + // LCOV_EXCL_BR_START 11:unexpected branch + BkupSetResponseNsfw(h_app, &query_result.size, sizeof(query_result.size), eFrameworkunifiedStatusOK); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } else if (hdr->command == BKUP_CMD_CHECK) { + if (query_result.nand) { + // LCOV_EXCL_BR_START 11:unexpected branch + ret = BkupCmdCheck(&response_nsfw, NVHALMEDIA_NAND, rcv_buf, &query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } else if (query_result.backup_dram) { + // LCOV_EXCL_BR_START 11:unexpected branch + ret = BkupCmdCheck(&response_nsfw, NVHALMEDIA_BACKUPDRAM, rcv_buf, &query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } else if (query_result.cache_dram) { + // LCOV_EXCL_BR_START 11:unexpected branch + ret = BkupCmdCheck(&response_nsfw, NVHALMEDIA_CACHEDRAM, rcv_buf, &query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } else { + ret = -3; + } + + if (ret == -1) { + // not exists + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Not exists:%s", hdr->item_name != 0 ? hdr->item_name : NULL); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + e_status = eFrameworkunifiedStatusFileLoadError; + } else if (ret == -2) { + // size error + e_status = eFrameworkunifiedStatusAccessError; + } else if (ret == -3) { + e_status = eFrameworkunifiedStatusFail; + } + } else { + /* + * Cache DRAM + */ + if (query_result.cache_dram) { + // LCOV_EXCL_BR_START 11:unexpected branch + ret = BkupHandlerFile(&response_nsfw, NVHALMEDIA_CACHEDRAM, rcv_buf, &query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + if (ret > 0) { + if (hdr->command == BKUP_CMD_READ) { + goto exit; + } + // LCOV_EXCL_BR_START 5: mmap's error case. + if (BkupTweakCommand(NVHALMEDIA_CACHEDRAM, &rcv_buf, + reinterpret_cast<int *>(&rcv_size), + &query_result) < 0) { + // LCOV_EXCL_BR_STOP 5: mmap's error case. + // LCOV_EXCL_START 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + e_status = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 5: mmap's error case. + } + hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + } + } + + /* + * Backup DRAM + */ + if (query_result.backup_dram) { + // LCOV_EXCL_BR_START 11:unexpected branch + ret = BkupHandlerFile(&response_nsfw, NVHALMEDIA_BACKUPDRAM, rcv_buf, &query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + if (ret > 0) { + if (hdr->command == BKUP_CMD_READ) { + goto exit; + } + // LCOV_EXCL_BR_START 5: mmap's error case. + if (BkupTweakCommand(NVHALMEDIA_BACKUPDRAM, &rcv_buf, + reinterpret_cast<int *>(&rcv_size), + &query_result) < 0) { + // LCOV_EXCL_BR_STOP 5: mmap's error case. + // LCOV_EXCL_START 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + e_status = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 5: mmap's error case. + } + hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_buf); + } + } + + /* + * NAND + */ + if (query_result.nand) { + bkup_itc_message_t snd_msg; + + if ((hdr->command == BKUP_CMD_READ) || (hdr->command == BKUP_CMD_DELETE) || (query_result.sync) || (ret == 0)) { + /* + * operation offload + */ + const char *client_name; + char system_info[MAX_SYS_INFO_SIZE]; + + if (g_bkup_nand_mqd == -1) { + // LCOV_EXCL_BR_START 5: mq_open's error case. + if ((g_bkup_nand_mqd = BkupItcMqopen("/" BKUP_THREAD_NAND, O_WRONLY | O_CREAT | O_NONBLOCK | O_CLOEXEC)) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_open's error case. + // LCOV_EXCL_START 5: mq_open's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_open:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5: mq_open's error case. + } + } + + if ((client_name = FrameworkunifiedGetMsgSrc(h_app)) == NULL) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "invalid client_name"); + e_status = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 4: NSFW error case. + } + FrameworkunifiedGetSystemInfo(h_app, system_info); // LCOV_EXCL_BR_LINE 11:unexpected branch. + + memset(&snd_msg, 0, sizeof(snd_msg)); + BkupStrlcpy(snd_msg.nand.client_name, client_name, sizeof(snd_msg.nand.client_name)); + snd_msg.nand.seq_id = static_cast<uint32_t>(strtoul(system_info, NULL, 16)); + snd_msg.nand.rcv_buf = rcv_buf; + snd_msg.nand.rcv_size = rcv_size; + + // LCOV_EXCL_BR_START 5: mq_send's error case. + if (mq_send(g_bkup_nand_mqd, reinterpret_cast<char *>(&snd_msg), sizeof(snd_msg), 0) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_send's error case. + // LCOV_EXCL_START 5: mq_send's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + int save_errno = errno; + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_send:%s", strerror(errno)); + e_status = eFrameworkunifiedStatusFail; + if (save_errno == EAGAIN) { + kill(g_bkup_nand_tid, SIGABRT); + } + goto exit; + // LCOV_EXCL_STOP 5: mq_send's error case. + } + FrameworkunifiedSetDeferredSyncResponse(h_app); // LCOV_EXCL_BR_LINE 11:unexpected branch. + hold_rcv_buf = true; + } else { + /* + * delay write + */ + if (g_bkup_delay_mqd == -1) { + // LCOV_EXCL_BR_START 5: mq_open's error case. + if ((g_bkup_delay_mqd = BkupItcMqopen("/" BKUP_THREAD_DELAY, O_WRONLY | O_CREAT | O_NONBLOCK | O_CLOEXEC)) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_open's error case. + // LCOV_EXCL_START 5: mq_open's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_open:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5: mq_open's error case. + } + } + + memset(&snd_msg, 0, sizeof(snd_msg)); + +// snd_msg.delay.terminate = false; + snd_msg.delay.cmd = BKUP_DELAY_CMD_REGIST; + + BkupStrlcpy(snd_msg.delay.item_name, hdr->item_name, sizeof(snd_msg.delay.item_name)); + + // LCOV_EXCL_BR_START 5: mq_send's error case. + if (mq_send(g_bkup_delay_mqd, reinterpret_cast<char *>(&snd_msg), sizeof(snd_msg), 0) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_send's error case. + // LCOV_EXCL_START 5: mq_send's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + int save_errno = errno; + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_send:%s", strerror(errno)); + e_status = eFrameworkunifiedStatusFail; + if (save_errno == EAGAIN) { + kill(g_bkup_delay_tid, SIGABRT); + } + goto exit; + // LCOV_EXCL_STOP 5: mq_send's error case. + } + } + } + } + +exit: + if (hold_rcv_buf == false && rcv_buf != MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case + munmap(rcv_buf, rcv_size); + } + return e_status; +} + + +/** + * Power callback handler + */ +EFrameworkunifiedStatus bkup_power_handler(HANDLE hApp) { + EFrameworkunifiedStatus eStatus = eFrameworkunifiedStatusOK; + uint32_t rcv_size = 0; + T_SS_SM_UserModeOnOffNotification_StructType power_status; + + if ((rcv_size = FrameworkunifiedGetMsgLength(hApp)) != sizeof(power_status)) { // LCOV_EXCL_BR_START 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + // LCOV_EXCL_START 4: NSFW error case + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedGetMsgLength: size fail:%d", rcv_size); + eStatus = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 4: NSFW error case + } + + // LCOV_EXCL_BR_START 4: NSFW error case + if ((eStatus = FrameworkunifiedGetMsgDataOfSize(hApp, &power_status, rcv_size, eSMRRelease)) != eFrameworkunifiedStatusOK) { + // LCOV_EXCL_BR_STOP 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + // LCOV_EXCL_START 4: NSFW error case + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "FrameworkunifiedGetMsgDataOfSize:%d", eStatus); + goto exit; + // LCOV_EXCL_STOP 4: NSFW error case + } + + if (g_bkup_internal_state != BKUP_STATE_NORMAL) { // LCOV_EXCL_BR_LINE 6:double check + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + // LCOV_EXCL_START 6:double check + FRAMEWORKUNIFIEDLOG(ZONE_WARN, __func__, "Invalid state:%d", g_bkup_internal_state); + goto exit; + // LCOV_EXCL_STOP 6:double check + } + + if (power_status.isUserModeOn == FALSE) { + bkup_itc_message_t snd_msg; + + if (g_bkup_delay_mqd == -1) { + // LCOV_EXCL_BR_START 5: mq_open's error case. + if ((g_bkup_delay_mqd = BkupItcMqopen("/" BKUP_THREAD_DELAY, O_WRONLY|O_CREAT|O_NONBLOCK|O_CLOEXEC)) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_open's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + // LCOV_EXCL_START 5: mq_open's error case. + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_open:%s", strerror(errno)); + eStatus = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 5: mq_open's error case. + } + } + + memset(&snd_msg, 0, sizeof(snd_msg)); + snd_msg.delay.cmd = BKUP_DELAY_CMD_PRE_ACCOFF; + + // LCOV_EXCL_BR_START 5: mq_send's error case. + if (mq_send(g_bkup_delay_mqd, (char *)&snd_msg, sizeof(snd_msg), 0) < 0) { + // LCOV_EXCL_BR_START 5: mq_send's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + // LCOV_EXCL_START 5: mq_send's error case. + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_send:%s", strerror(errno)); + eStatus = eFrameworkunifiedStatusFail; + goto exit; + // LCOV_EXCL_STOP 5: mq_send's error case. + } + } + +exit: + return eStatus; +} + + +/** + * thread's response + */ +static int BkupSetResponseThread(void *opt, void *buf, int size, EFrameworkunifiedStatus ret_value) { + HANDLE response_mq; + char invoker_name[MAX_QUEUE_NAME_SIZE]; + if (opt == NULL) { + FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "opt is NULL"); + return -1; + } + bkup_itc_message_t *msg = reinterpret_cast<bkup_itc_message_t *>(opt); + EFrameworkunifiedStatus e_status; + // LCOV_EXCL_BR_START 11:unexpected branch. + McCreateInvokerName(msg->nand.client_name, 0, invoker_name, sizeof(invoker_name)); + // LCOV_EXCL_BR_STOP 11:unexpected branch. + + if (g_bkup_response_mq == NULL) { + g_bkup_response_mq = new g_bkup_response_mq_t; // LCOV_EXCL_BR_LINE 11:except,C++ operator + } + g_bkup_response_mq_t::iterator mq_it = g_bkup_response_mq->find(invoker_name); // LCOV_EXCL_BR_LINE 11:except,C++ STL + if (mq_it != g_bkup_response_mq->end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + response_mq = mq_it->second; // LCOV_EXCL_BR_LINE 11:except,C++ STL + } else { + if ((response_mq = McOpenSyncSender(invoker_name)) == NULL) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mcOpenSyncSender"); + return -1; + // LCOV_EXCL_STOP 4: NSFW error case. + } + g_bkup_response_mq->insert(std::make_pair(invoker_name, response_mq)); // LCOV_EXCL_BR_LINE 11:except,C++ STL + } + + // LCOV_EXCL_BR_START 11:unexpected branch. + e_status = McSendSyncResponse(response_mq, MN_NS_BACKUPMGR, BACKUP_CID, msg->nand.seq_id, ret_value, size, buf); + // LCOV_EXCL_BR_STOP 11:unexpected branch. + return (e_status == eFrameworkunifiedStatusOK) ? 0 : -1; // LCOV_EXCL_BR_LINE 11:unexpected branch +} + +/** + * NAND Thread + */ +void *BkupNandThread(void *arg) { + mqd_t mqd; + struct pollfd fds[1]; + bkup_itc_message_t rcv_msg; + bkup_protocol_header_t *hdr; + bkup_query_result_t query_result; + bkup_response_t response_thread = {BkupSetResponseThread, NULL}; + + signal_handler p_signal = SignalHandlerFuncForMsgHandleThread; + signal(SIGUSR1, p_signal); + g_nand_thread_id = pthread_self(); + + if (prctl(PR_SET_NAME, BKUP_THREAD_NAND) < 0) { // LCOV_EXCL_BR_LINE 5: prctl's error case. + // LCOV_EXCL_START 5: prctl's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "prctl(PR_SET_NAME):%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5: prctl's error case. + } + + // LCOV_EXCL_BR_START 5: mq_open's error case. + if ((mqd = BkupItcMqopen("/" BKUP_THREAD_NAND, O_RDONLY | O_CREAT | O_CLOEXEC)) < -1) { + // LCOV_EXCL_BR_STOP 5: mq_open's error case. + // LCOV_EXCL_START 5: mq_open's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_open:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5: mq_open's error case. + } + g_bkup_nand_tid = static_cast<int>(syscall(__NR_gettid)); + + fds[0].fd = mqd; + fds[0].events = POLLIN; + + while (1) { + int ret = poll(fds, sizeof(fds) / sizeof(struct pollfd), -1); // LCOV_EXCL_BR_LINE 11:unexpected branch + if (ret < 0) { // LCOV_EXCL_BR_LINE 5: poll's error case. + // LCOV_EXCL_START 5: poll's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + if (errno == EINTR) { + continue; + } + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "poll errno:%s", strerror(errno)); + // LCOV_EXCL_STOP 5: poll's error case. + } else { + if ((fds[0].revents & POLLIN) != 0) { + // LCOV_EXCL_BR_START 5: mq_receive's error case. + if (mq_receive(mqd, reinterpret_cast<char *>(&rcv_msg), sizeof(rcv_msg), NULL) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_receive's error case. + // LCOV_EXCL_START 5: mq_receive's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + if (errno != EINTR) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_receive:%s", strerror(errno)); + } + continue; + // LCOV_EXCL_STOP 5: mq_receive's error case. + } + hdr = reinterpret_cast<bkup_protocol_header_t *>(rcv_msg.nand.rcv_buf); + BkupParamGet(hdr->item_name, &query_result); // LCOV_EXCL_BR_LINE 11:unexpected branch + response_thread.opt = &rcv_msg; + // LCOV_EXCL_BR_START 11:unexpected branch + ret = BkupHandlerFile(&response_thread, NVHALMEDIA_NAND, rcv_msg.nand.rcv_buf, &query_result); + // LCOV_EXCL_BR_STOP 11:unexpected branch + + munmap(rcv_msg.nand.rcv_buf, rcv_msg.nand.rcv_size); + } + } + } + + return NULL; +} + +/* + * delay backup thread + */ +typedef struct { + int fd; + std::string name; +} bkup_delay_t; // LCOV_EXCL_BR_LINE 11:except,C++ STL + +static int BkupDelayTimerAdd(int efd, const char *item_name, time_t backup_cycle) { + int ret = -1; + struct epoll_event ev; + bkup_delay_t *timer_ev = new bkup_delay_t; // LCOV_EXCL_BR_LINE 11:except,C++ operator + struct itimerspec itime; + + if ((timer_ev->fd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0) { // LCOV_EXCL_BR_LINE 5: timerfd_create's error case. + // LCOV_EXCL_START 5: timerfd_create's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "timerfd_create:%s", strerror(errno)); + goto exit; + // LCOV_EXCL_STOP 5: timerfd_create's error case. + } + timer_ev->name = item_name; // LCOV_EXCL_BR_LINE 11:except,C++ STL + + ev.events = EPOLLIN; + ev.data.ptr = timer_ev; + if (epoll_ctl(efd, EPOLL_CTL_ADD, timer_ev->fd, &ev) < 0) { // LCOV_EXCL_BR_LINE 5: epoll_ctl's error case. + // LCOV_EXCL_START 5: epoll_ctl's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "epoll_ctl:%s", strerror(errno)); + goto exit; + // LCOV_EXCL_STOP 5: epoll_ctl's error case. + } + + memset(&itime, 0, sizeof(itime)); + itime.it_value.tv_sec = backup_cycle; + itime.it_interval.tv_sec = backup_cycle; + + if (timerfd_settime(timer_ev->fd, 0, &itime, NULL) < 0) { // LCOV_EXCL_BR_LINE 5: timerfd_settime's error case. + // LCOV_EXCL_START 5: timerfd_settime's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "timerfd_settime:%s", strerror(errno)); + epoll_ctl(efd, EPOLL_CTL_DEL, timer_ev->fd, &ev); + goto exit; + // LCOV_EXCL_STOP 5: timerfd_settime's error case. + } + ret = 0; + +exit: + if (ret < 0) { // LCOV_EXCL_BR_LINE 5: C API's error case. + // LCOV_EXCL_START 5: C API's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + if (timer_ev->fd >= 0) { + if (close(timer_ev->fd) < 0) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "timerfd_settime:%s", strerror(errno)); + } + } + delete timer_ev; + } + // LCOV_EXCL_STOP 5: C API's error case. + return ret; +} + +static uint64_t *g_bkup_syncreq; +static pthread_rwlock_t g_syncreq_rwlock = PTHREAD_RWLOCK_INITIALIZER; +#define BKUP_SYNCREQ_SIZE (4096) +#define BKUP_SYNCREQ_ID_MAX (BKUP_SYNCREQ_SIZE * 8 - 1) +#define BKUP_SYNCREQ_NAME "syncreq" + +static int BkupSyncreqInit(void) { + int ret = -1; + char *map; + + map = reinterpret_cast<char *>(mmap(NULL, BKUP_SYNCREQ_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0)); + if (map == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + // LCOV_EXCL_START 5: mmap's error case. + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap failed"); + goto exit; + // LCOV_EXCL_STOP 5: mmap's error case. + } + g_bkup_syncreq = reinterpret_cast<uint64_t *>(map); + memset(g_bkup_syncreq, 0, BKUP_SYNCREQ_SIZE); + + pthread_rwlock_wrlock(&g_syncreq_rwlock); + BkupBufferWriteToNv(NVHALMEDIA_BACKUPDRAM, BKUP_SYNCREQ_NAME, + reinterpret_cast<char *>(g_bkup_syncreq), + BKUP_SYNCREQ_SIZE, NULL); + pthread_rwlock_unlock(&g_syncreq_rwlock); + ret = 0; + +exit: + return ret; +} + +static void BkupSyncreqTerm(void) { + if (g_bkup_syncreq != NULL) { // LCOV_EXCL_BR_LINE 6:g_bkup_syncreq will not be NULL + munmap(g_bkup_syncreq, BKUP_SYNCREQ_SIZE); + g_bkup_syncreq = NULL; + } +} + +static int BkupSyncreqSet(int id) { + if (g_bkup_syncreq == NULL) { // LCOV_EXCL_BR_LINE 6:g_bkup_syncreq will not be NULL + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + return -1; // LCOV_EXCL_LINE 5: mmap's error case. + } + if (id > BKUP_SYNCREQ_ID_MAX) { + return -1; + } + if (!(*(g_bkup_syncreq + id / 64) & (1ULL << (id % 64)))) { + *(g_bkup_syncreq + id / 64) |= (1ULL << (id % 64)); + pthread_rwlock_wrlock(&g_syncreq_rwlock); + BkupBufferWriteToNv(NVHALMEDIA_BACKUPDRAM, BKUP_SYNCREQ_NAME, + reinterpret_cast<char *>(g_bkup_syncreq), + BKUP_SYNCREQ_SIZE, NULL); + pthread_rwlock_unlock(&g_syncreq_rwlock); + } + return 0; +} + +static int BkupSyncreqClear(int id) { + if (g_bkup_syncreq == NULL) { // LCOV_EXCL_BR_LINE 6:g_bkup_syncreq will not be NULL + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + return -1; // LCOV_EXCL_LINE 5: mmap's error case. + } + if (id > BKUP_SYNCREQ_ID_MAX) { + return -1; + } + if (*(g_bkup_syncreq + id / 64) & (1ULL << (id % 64))) { + *(g_bkup_syncreq + id / 64) &= ~(1ULL << (id % 64)); + pthread_rwlock_wrlock(&g_syncreq_rwlock); + BkupBufferWriteToNv(NVHALMEDIA_BACKUPDRAM, BKUP_SYNCREQ_NAME, + reinterpret_cast<char *>(g_bkup_syncreq), + BKUP_SYNCREQ_SIZE, NULL); + pthread_rwlock_unlock(&g_syncreq_rwlock); + } + + return 0; +} + +static inline int BkupPopcnt64(uint64_t x) { + uint64_t n; + + n = (x >> 1) & 0x7777777777777777ULL; + x = x - n; + n = (n >> 1) & 0x7777777777777777ULL; + x = x - n; + n = (n >> 1) & 0x7777777777777777ULL; + x = x - n; + x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fULL; + x = x * 0x0101010101010101ULL; + return static_cast<int>(x >> 56); +} + +static int BkupSyncreqSearch(void) { + int i; + + if (g_bkup_syncreq == NULL) { // LCOV_EXCL_BR_LINE 6:g_bkup_syncreq will not be NULL + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + return -1; // LCOV_EXCL_LINE 5: mmap's error case. + } + + for (i = 0; i < static_cast<int>(BKUP_SYNCREQ_SIZE / sizeof(uint64_t)); i++) { + if (*(g_bkup_syncreq + i) != 0) { + uint64_t bits, mrb1; // most right bit 1 + bits = *(g_bkup_syncreq + i); + mrb1 = bits & (-bits); + return i * 64 + BkupPopcnt64(mrb1 - 1); + } + } + + return -1; +} + +static void BkupSyncreqDone(bool skip_cache) { + int id; + uint64_t start, end; + + start = BkupTimerReal(); + + while ((id = BkupSyncreqSearch()) >= 0) { + char item_name[64]; + bkup_query_result_t query_result; + + if (BkupParamGetNumid(id, &query_result, item_name, sizeof(item_name)) < 0) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid num_id:%d", id); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + } else { + if (query_result.cache_dram) { + if (!skip_cache) { + BkupMediaCopyFromNv(query_result.category_name, item_name, + NVHALMEDIA_CACHEDRAM, NVHALMEDIA_NAND, NULL, + NULL); + } + } else if (query_result.backup_dram) { + // LCOV_EXCL_BR_START 11:unexpected branch + BkupMediaCopyFromNv(query_result.category_name, item_name, + NVHALMEDIA_BACKUPDRAM, NVHALMEDIA_NAND, NULL, NULL); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } + } + + BkupSyncreqClear(id); // LCOV_EXCL_BR_LINE 11:unexpected branch + + } + + end = BkupTimerReal(); + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "spent:%" PRIu64 ".%06" PRIu64 "ms", + static_cast<uint64_t>((end - start) / 1000000), + static_cast<uint64_t>((end - start) % 1000000)); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" +} + +void BkupSyncreqRestart(void) { + char *map; + + map = reinterpret_cast<char *>(mmap(NULL, BKUP_SYNCREQ_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0)); + if (map == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5: mmap's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + // LCOV_EXCL_START 5: mmap's error case. + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap failed"); + goto exit; + // LCOV_EXCL_STOP 5: mmap's error case. + } + g_bkup_syncreq = reinterpret_cast<uint64_t *>(map); + + if (BkupBufferReadFromNv(NVHALMEDIA_BACKUPDRAM, BKUP_SYNCREQ_NAME, + reinterpret_cast<char *>(g_bkup_syncreq), + BKUP_SYNCREQ_SIZE, NULL) < 0) { + goto exit; + } + BkupSyncreqDone(true); + BkupSyncreqTerm(); + +exit: + return; +} + +void *BkupDelayThread(void *arg) { + mqd_t mqd; + int efd; + struct epoll_event ev; + bkup_delay_t *mq_ev; + bkup_itc_message_t rcv_msg; + std::map<std::string, int> delay_req; // LCOV_EXCL_BR_LINE 11:except,C++ STL + + signal_handler p_signal = SignalHandlerFuncForMsgHandleThread; + signal(SIGUSR1, p_signal); + g_delay_thread_id = pthread_self(); + + + if (prctl(PR_SET_NAME, BKUP_THREAD_DELAY) < 0) { // LCOV_EXCL_BR_LINE 5: prctl's error case. + // LCOV_EXCL_START 5: prctl's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "prctl(PR_SET_NAME):%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5: prctl's error case. + } + + // LCOV_EXCL_BR_START 5: mq_open's error case. + if ((mqd = BkupItcMqopen("/" BKUP_THREAD_DELAY, O_RDONLY | O_CREAT | O_CLOEXEC)) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_open's error case. + // LCOV_EXCL_START 5: mq_open's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_open:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5: mq_open's error case. + } + + if ((efd = epoll_create(MAX_FD_EPOLL)) < 0) { // LCOV_EXCL_BR_LINE 5: epoll_create's error case. + // LCOV_EXCL_START 5: epoll_create's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "epoll_create:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5: epoll_create's error case. + } + g_bkup_delay_tid = static_cast<int>(syscall(__NR_gettid)); + + mq_ev = new bkup_delay_t; // LCOV_EXCL_BR_LINE 11:except,C++ operator + mq_ev->fd = static_cast<int>(mqd); + mq_ev->name = "mq"; // LCOV_EXCL_BR_LINE 11:except,C++ STL + + ev.events = EPOLLIN; + ev.data.ptr = mq_ev; + // LCOV_EXCL_BR_START 5: epoll_ctl's error case. + if (epoll_ctl(efd, EPOLL_CTL_ADD, static_cast<int>(mqd), &ev) < 0) { + // LCOV_EXCL_BR_STOP 5: epoll_ctl's error case. + // LCOV_EXCL_START 5: epoll_ctl's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "epoll_ctl:%s", strerror(errno)); + exit(EXIT_FAILURE); + // LCOV_EXCL_STOP 5: epoll_ctl's error case. + } + + while (1) { + struct epoll_event events[MAX_FD_EPOLL]; + int nfds; + + nfds = epoll_wait(efd, events, MAX_FD_EPOLL, -1); // LCOV_EXCL_BR_LINE 11:unexpected branch + if (nfds < 0) { // LCOV_EXCL_BR_LINE 5: epoll_wait's error case. + // LCOV_EXCL_START 5: epoll_wait's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + if (errno != EINTR) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "epoll_wait:%s", strerror(errno)); + } + continue; + // LCOV_EXCL_STOP 5: epoll_wait's error case. + } + + for (int i = 0; i < nfds; i++) { + bkup_delay_t *cur_ev = reinterpret_cast<bkup_delay_t *>(events[i].data.ptr); + + if (cur_ev->fd == mqd) { + /* + * mq + */ + // LCOV_EXCL_BR_START 5: mq_receive's error case. + if (mq_receive(mqd, reinterpret_cast<char *>(&rcv_msg), sizeof(rcv_msg), NULL) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_receive's error case. + // LCOV_EXCL_START 5: mq_receive's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + if (errno != EINTR) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_receive:%s", strerror(errno)); + } + continue; + // LCOV_EXCL_STOP 5: mq_receive's error case. + } + +#if 0 + if (rcv_msg.delay.terminate) { + // terminate request + // shutdown sync + BkupSyncreqDone(false); // LCOV_EXCL_BR_LINE 11:unexpected branch + + for (std::map<std::string, int>::iterator i = delay_req.begin(); i != delay_req.end(); ++i) { + i->second = 0; // LCOV_EXCL_BR_LINE 11:except,C++ STL + } + + // terminate finish response + int64_t term_event = 1; + // LCOV_EXCL_BR_START 5: write's error case. + if (write(rcv_msg.delay.event_fd, &term_event, sizeof(term_event)) < 0) { + // LCOV_EXCL_BR_STOP 5: write's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "write:%s", strerror(errno)); // LCOV_EXCL_LINE 5: write's error case. + } + } else { + // delay request + bkup_query_result_t query_result; + BkupParamGet(rcv_msg.delay.item_name, &query_result); // LCOV_EXCL_BR_LINE 11:unexpected branch + + if (query_result.backup_cycle > 0) { // LCOV_EXCL_BR_LINE 11:unexpected branch + if (delay_req.find(rcv_msg.delay.item_name) != delay_req.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + delay_req[rcv_msg.delay.item_name]++; // LCOV_EXCL_BR_LINE 11:except,C++ STL + } else { + // LCOV_EXCL_BR_START 11:unexpected branch + BkupDelayTimerAdd(efd, rcv_msg.delay.item_name, query_result.backup_cycle); + // LCOV_EXCL_BR_STOP 11:unexpected branch + delay_req[rcv_msg.delay.item_name] = 1; // LCOV_EXCL_BR_LINE 11:unexpected branch + } + + if (BkupSyncreqSet(query_result.id) < 0) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid num_id:%d", query_result.id); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + } + } else { + // write to ACC OFF + bkup_query_result_t query_result; + if (BkupParamGet(rcv_msg.delay.item_name, &query_result) < 0) { // LCOV_EXCL_BR_LINE 11:except,C++ STL + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid item_name:%s", + rcv_msg.delay.item_name != 0 ? rcv_msg.delay.item_name : NULL); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + } else { + if (BkupSyncreqSet(query_result.id) < 0) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid num_id:%d", query_result.id); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + } + } + } + } +#endif + switch (rcv_msg.delay.cmd) { + case BKUP_DELAY_CMD_TERM: + case BKUP_DELAY_CMD_PRE_ACCOFF: + /* + * terminate or pre-acc_off request + */ + // shutdown sync + BkupSyncreqDone(false); + + for (std::map<std::string, int>::iterator i = delay_req.begin(); i != delay_req.end(); ++i) { + i->second = 0; + } + + if (rcv_msg.delay.cmd == BKUP_DELAY_CMD_TERM) { + BkupSyncreqTerm(); + + // terminate finish response + int64_t term_event = 1; + // LCOV_EXCL_BR_START 5: write's error case. + if (write(rcv_msg.delay.event_fd, &term_event, sizeof(term_event)) < 0) { + // LCOV_EXCL_BR_STOP 5: write's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "write:%s", strerror(errno)); // LCOV_EXCL_LINE 5: write's error case. + } + } + break; + + case BKUP_DELAY_CMD_REGIST: + // delay regist request + bkup_query_result_t query_result; + BkupParamGet(rcv_msg.delay.item_name, &query_result); + + if (query_result.backup_cycle > 0) { + if (delay_req.find(rcv_msg.delay.item_name) != delay_req.end()) { + delay_req[rcv_msg.delay.item_name]++; + } else { + BkupDelayTimerAdd(efd, rcv_msg.delay.item_name, query_result.backup_cycle); + delay_req[rcv_msg.delay.item_name] = 1; + } + + if (BkupSyncreqSet(query_result.id) < 0) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid num_id:%d", query_result.id); + } + } else { + // wite to ACC OFF + bkup_query_result_t query_result; + if (BkupParamGet(rcv_msg.delay.item_name, &query_result) < 0) { // LCOV_EXCL_BR_LINE 6:double check + // LCOV_EXCL_START 6:double check + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid item_name:%s", rcv_msg.delay.item_name); + // LCOV_EXCL_STOP 6:double check + } else { + if (BkupSyncreqSet(query_result.id) < 0) { + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid num_id:%d", query_result.id); + } + } + } + break; + } + + } else { + /* + * timerfd + */ + uint64_t exp; + if (read(cur_ev->fd, &exp, sizeof(exp)) < 0) { // LCOV_EXCL_BR_LINE 5: read's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "read:%s", strerror(errno)); // LCOV_EXCL_LINE 5: read's error case. + } + + if (delay_req[cur_ev->name] > 0) { // LCOV_EXCL_BR_LINE 11:unexpected branch + bkup_query_result_t query_result; + BkupParamGet(cur_ev->name.c_str(), &query_result); // LCOV_EXCL_BR_LINE 11:unexpected branch + + if (query_result.cache_dram) { + // LCOV_EXCL_BR_START 11:unexpected branch + pthread_rwlock_t *src_rwlock = BkupGetRwlock( + cur_ev->name.c_str(), NVHALMEDIA_CACHEDRAM, &query_result); + pthread_rwlock_t *dst_rwlock = BkupGetRwlock( + cur_ev->name.c_str(), NVHALMEDIA_NAND, &query_result); + BkupMediaCopyFromNv(query_result.category_name, + cur_ev->name.c_str(), NVHALMEDIA_CACHEDRAM, + NVHALMEDIA_NAND, src_rwlock, dst_rwlock); + BkupMediaCopyFromNv(query_result.category_name, + cur_ev->name.c_str(), NVHALMEDIA_CACHEDRAM, + NVHALMEDIA_NAND, NULL, NULL); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } else if (query_result.backup_dram) { + // LCOV_EXCL_BR_START 11:unexpected branch + pthread_rwlock_t *src_rwlock = BkupGetRwlock( + cur_ev->name.c_str(), NVHALMEDIA_BACKUPDRAM, &query_result); + pthread_rwlock_t *dst_rwlock = BkupGetRwlock( + cur_ev->name.c_str(), NVHALMEDIA_NAND, &query_result); + BkupMediaCopyFromNv(query_result.category_name, + cur_ev->name.c_str(), NVHALMEDIA_BACKUPDRAM, + NVHALMEDIA_NAND, src_rwlock, dst_rwlock); + // LCOV_EXCL_BR_STOP 11:unexpected branch + } + delay_req[cur_ev->name] = 0; // LCOV_EXCL_BR_LINE 11:unexpected branch + if (BkupSyncreqClear(query_result.id) < 0) { + // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h" + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Invalid num_id:%d", query_result.id); + // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h" + } + } else { + // not update. timer delte + // LCOV_EXCL_BR_START 5: epoll_ctl's error case. + if (epoll_ctl(efd, EPOLL_CTL_DEL, cur_ev->fd, &events[i]) < 0) { + // LCOV_EXCL_BR_STOP 5: epoll_ctl's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "epoll_ctl:%s", strerror(errno)); // LCOV_EXCL_LINE 5: epoll_ctl's error case. + } + if (close(cur_ev->fd) < 0) { // LCOV_EXCL_BR_LINE 5: close's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "close:%s", strerror(errno)); // LCOV_EXCL_LINE 5: close's error case. + } + delay_req.erase(cur_ev->name); // LCOV_EXCL_BR_LINE 11:unexpected branch + delete cur_ev; // LCOV_EXCL_BR_LINE 11:except,C++ operator + } + } + } + } + + return NULL; +} + +/** + * Terminate handler + */ +EFrameworkunifiedStatus BkupTerminateHandler(HANDLE h_app) { + bkup_itc_message_t snd_msg; + int event_fd; + int64_t term_event; + + g_bkup_internal_state = BKUP_STATE_TERM; + + if (g_bkup_delay_mqd == -1) { + // LCOV_EXCL_BR_START 5: mq_open's error case. + if ((g_bkup_delay_mqd = BkupItcMqopen("/" BKUP_THREAD_DELAY, O_WRONLY | O_CREAT | O_NONBLOCK | O_CLOEXEC)) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_open's error case. + // LCOV_EXCL_START 5: mq_open's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_open:%s", strerror(errno)); + return eFrameworkunifiedStatusFail; + // LCOV_EXCL_STOP 5: mq_open's error case. + } + } + + if ((event_fd = eventfd(0, 0)) < 0) { // LCOV_EXCL_BR_LINE 5: eventfd's error case. + // LCOV_EXCL_START 5: eventfd's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "eventfd:%s", strerror(errno)); + return eFrameworkunifiedStatusFail; + // LCOV_EXCL_STOP 5: eventfd's error case. + } + + memset(&snd_msg, 0, sizeof(snd_msg)); + +// snd_msg.delay.terminate = true; + snd_msg.delay.cmd = BKUP_DELAY_CMD_TERM; + + snd_msg.delay.event_fd = event_fd; + + // LCOV_EXCL_BR_START 5: mq_send's error case. + if (mq_send(g_bkup_delay_mqd, reinterpret_cast<char *>(&snd_msg), sizeof(snd_msg), 0) < 0) { + // LCOV_EXCL_BR_STOP 5: mq_send's error case. + // LCOV_EXCL_START 5: mq_send's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mq_send:%s", strerror(errno)); + return eFrameworkunifiedStatusFail; + // LCOV_EXCL_STOP 5: mq_send's error case. + } + + while (1) { + if (read(event_fd, &term_event, sizeof(term_event)) < 0) { // LCOV_EXCL_BR_LINE 5: read's error case. + // LCOV_EXCL_START 5: read's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + if (errno == EINTR) { + continue; + } + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "read:%s", strerror(errno)); + return eFrameworkunifiedStatusFail; + // LCOV_EXCL_STOP 5: read's error case. + } else { + break; + } + } + if (close(event_fd) < 0) { // LCOV_EXCL_BR_LINE 5: close's error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "close:%s", strerror(errno)); // LCOV_EXCL_LINE 5: close's error case. + } + + return eFrameworkunifiedStatusOK; +} + +/** + * Init handler + */ +EFrameworkunifiedStatus BkupInitHandler(HANDLE h_app) { + BkupSyncreqRestart(); + BkupSyncreqInit(); + + g_bkup_internal_state = BKUP_STATE_NORMAL; + + return eFrameworkunifiedStatusOK; +} |