2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <other_service/VP_GetEnv.h>
21 #include <sys/types.h>
24 #include <libxml/xmlerror.h>
25 #include <libxml/parser.h>
26 #include <libxml/SAX2.h>
33 #include "bkup_param.h"
34 #include "bkup_backupmanagerlog.h"
35 #include "bkup_util.h"
37 #define BKUP_XML_PATH_MAX 100
38 #define BKUP_XML_PATH "/usr/agl/conf/BS/ns/backup_manager/rodata/"
39 #define BKUP_XML_PREFIX "backup_"
40 #define BKUP_XML_EXTENSION ".xml"
42 #define BKUP_AREA_1 "AREA1"
43 #define BKUP_AREA_2 "AREA2"
44 #define BKUP_BRAND_1 "BRAND1"
45 #define BKUP_BRAND_2 "BRAND2"
46 #define BKUP_GRADE_1 "GRADE1"
47 #define BKUP_GRADE_2 "GRADE2"
48 #define BKUP_DESTINATION_TYPE_AREA1_TE "AREA1_TE"
49 #define BKUP_DESTINATION_TYPE_AREA1_L "AREA1_L"
50 #define BKUP_DESTINATION_TYPE_AREA2_T "AREA2_T"
51 #define BKUP_DESTINATION_TYPE_AREA2_TE "AREA2_TE"
53 #define BKUP_DESTINATION_STR_MAX 10
55 char area[VP_MAX_LENGTH];
56 char brand[VP_MAX_LENGTH];
57 char grade[VP_MAX_LENGTH];
58 char destination[BKUP_DESTINATION_STR_MAX];
61 const BkupDestinationTbl kDestinationTbl[] = {
63 {BKUP_AREA_1, BKUP_BRAND_1, BKUP_GRADE_1, BKUP_DESTINATION_TYPE_AREA1_TE},
64 {BKUP_AREA_1, BKUP_BRAND_1, BKUP_GRADE_2, BKUP_DESTINATION_TYPE_AREA1_TE},
65 {BKUP_AREA_1, BKUP_BRAND_2, BKUP_GRADE_1, BKUP_DESTINATION_TYPE_AREA1_L},
66 {BKUP_AREA_1, BKUP_BRAND_2, BKUP_GRADE_2, BKUP_DESTINATION_TYPE_AREA1_L},
68 {BKUP_AREA_2, BKUP_BRAND_1, BKUP_GRADE_1, BKUP_DESTINATION_TYPE_AREA2_TE},
69 {BKUP_AREA_2, BKUP_BRAND_1, BKUP_GRADE_2, BKUP_DESTINATION_TYPE_AREA2_TE},
70 {BKUP_AREA_2, BKUP_BRAND_2, BKUP_GRADE_1, BKUP_DESTINATION_TYPE_AREA2_T},
71 {BKUP_AREA_2, BKUP_BRAND_2, BKUP_GRADE_2, BKUP_DESTINATION_TYPE_AREA2_T},
74 typedef std::string Category;
83 typedef std::map<Category, CategoryProperty> CategoryTable;
85 typedef std::string Item;
91 } ItemProperty; // LCOV_EXCL_BR_LINE 11:except,C++ STL
92 typedef std::map<Item, ItemProperty> ItemTable;
93 typedef std::map<int, Item> IdTable;
97 CategoryTable category_table;
100 } BackupParams; // LCOV_EXCL_BR_LINE 11:except,C++ STL
102 static BackupParams *g_backup_params = NULL;
104 static void StartElementNs(void *ctx, const xmlChar *localname,
105 const xmlChar *prefix, const xmlChar *uri,
106 int nb_namespaces, const xmlChar **namespaces,
107 int nb_attributes, int nb_defaulted,
108 const xmlChar **attributes) {
110 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "ctx is NULL");
113 if (localname == NULL) {
114 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "localname is NULL");
117 BackupParams *p_backup_params = static_cast<BackupParams *>(ctx);
118 std::string tag = (const char *)localname; // LCOV_EXCL_BR_LINE 11:except,C++ STL
119 if (tag.compare("backup") == 0) { // LCOV_EXCL_BR_LINE 11:except,C++ STL
121 } else if (tag.compare("category") == 0) { // LCOV_EXCL_BR_LINE 11:except,C++ STL
122 CategoryProperty category_attr = {false, false, false, false, false, 0};
123 std::string category_name; // LCOV_EXCL_BR_LINE 11:except,C++ STL
125 for (int i = 0; i < nb_attributes; i++) {
126 // LCOV_EXCL_BR_START 11:except,C++ STL
127 std::string localname = (const char *)attributes[i * 5];
128 std::string value((const char *)attributes[i * 5 + 3], (const char *)attributes[i * 5 + 4]);
129 if (localname.compare("name") == 0) {
130 category_name = value;
131 } else if (localname.compare("nand") == 0) {
132 if (value.compare("true") == 0) {
133 category_attr.nand = true;
135 } else if (localname.compare("backupDram") == 0) {
136 if (value.compare("true") == 0) {
137 category_attr.backup_dram = true;
139 } else if (localname.compare("cacheDram") == 0) {
140 if (value.compare("true") == 0) {
141 category_attr.cache_dram = true;
143 } else if (localname.compare("sync") == 0) {
144 if (value.compare("true") == 0) {
145 category_attr.sync = true;
147 } else if (localname.compare("encrypt") == 0) {
148 if (value.compare("true") == 0) {
149 category_attr.encrypt = true;
151 } else if (localname.compare("backupCycle") == 0) {
152 category_attr.backup_cycle = atoi(value.c_str());
153 // LCOV_EXCL_BR_STOP 11:except,C++ STL
155 // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h"
156 FRAMEWORKUNIFIEDLOG(ZONE_WARN, __func__, "Unknown attribute:%s", localname.c_str());
157 // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h"
161 // LCOV_EXCL_BR_START 11:except,C++ STL
162 CategoryTable::iterator c_it = p_backup_params->category_table.find(category_name);
163 // LCOV_EXCL_BR_STOP 11:except,C++ STL
164 if (c_it != p_backup_params->category_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL
165 // LCOV_EXCL_START 200:Execute in server start period
166 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
167 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "duplicate category:%s", category_name.c_str());
169 // LCOV_EXCL_STOP 200:Execute in server start period
171 // LCOV_EXCL_BR_START 11:except,C++ STL
172 p_backup_params->category_table.insert(std::make_pair(category_name, category_attr));
173 // LCOV_EXCL_BR_STOP 11:except,C++ STL
174 p_backup_params->current = category_name; // LCOV_EXCL_BR_LINE 11:except,C++ STL
175 } else if (tag.compare("item") == 0) { // LCOV_EXCL_BR_LINE 11:except,C++ STL
176 if (p_backup_params->current.compare("") == 0) { // LCOV_EXCL_BR_LINE 11:except,C++ STL
177 // LCOV_EXCL_START 200:Execute in server start period
178 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
179 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Detect item before category");
181 // LCOV_EXCL_STOP 200:Execute in server start period
184 ItemProperty item_property = {0, 0, NULL, p_backup_params->current}; // LCOV_EXCL_BR_LINE 11:except,C++ STL
185 std::string item_name; // LCOV_EXCL_BR_LINE 11:except,C++ STL
187 for (int i = 0; i < nb_attributes; i++) {
188 // LCOV_EXCL_BR_START 11:except,C++ STL
189 std::string localname = (const char *)attributes[i * 5];
190 std::string value((const char *)attributes[i * 5 + 3], (const char *)attributes[i * 5 + 4]);
191 if (localname.compare("name") == 0) {
193 } else if (localname.compare("id") == 0) {
194 item_property.id = atoi(value.c_str());
195 } else if (localname.compare("size") == 0) {
196 item_property.size = atoi(value.c_str());
197 // LCOV_EXCL_BR_STOP 11:except,C++ STL
199 // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h"
200 FRAMEWORKUNIFIEDLOG(ZONE_WARN, __func__, "Unknown attribute:%s", localname.c_str());
201 // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h"
205 ItemTable::iterator i_it = p_backup_params->item_table.find(item_name); // LCOV_EXCL_BR_LINE 11:except,C++ STL
206 if (i_it != p_backup_params->item_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL
207 // LCOV_EXCL_START 200:Execute in server start period
208 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
209 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Duplicate item:%s", item_name.c_str());
211 // LCOV_EXCL_STOP 200:Execute in server start period
213 // LCOV_EXCL_BR_START 11:except,C++ STL
214 p_backup_params->item_table.insert(std::make_pair(item_name, item_property));
215 // LCOV_EXCL_BR_STOP 11:except,C++ STL
217 IdTable::iterator id_it = p_backup_params->id_table.find(item_property.id); // LCOV_EXCL_BR_LINE 11:except,C++ STL
218 if (id_it != p_backup_params->id_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL
219 // LCOV_EXCL_START 200:Execute in server start period
220 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
221 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Duplicate id:%d", item_property.id);
223 // LCOV_EXCL_STOP 200:Execute in server start period
225 // LCOV_EXCL_BR_START 11:except,C++ STL
226 p_backup_params->id_table.insert(std::make_pair(item_property.id, item_name));
227 // LCOV_EXCL_BR_STOP 11:except,C++ STL
229 // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h"
230 FRAMEWORKUNIFIEDLOG(ZONE_WARN, __func__, "Unknown tag:%s", localname);
231 // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h"
235 static int BkupGetXmlPath(char* path) {
236 if (path == NULL) { // LCOV_EXCL_BR_LINE 6:Excluded as no NULL is currently passed
237 // LCOV_EXCL_START 6:Excluded as no NULL is currently passed
238 AGL_ASSERT_NOT_TESTED();
239 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "path is NULL");
241 // LCOV_EXCL_STOP 6:Excluded as no NULL is currently passed
243 memset(path, 0, BKUP_XML_PATH_MAX);
244 char param_area[VP_MAX_LENGTH] = "";
245 VP_GetEnv(VP_VEHICLEPARAMETERLIBRARY_AREA, param_area);
246 char param_brand[VP_MAX_LENGTH] = "";
247 VP_GetEnv(VEHICLEPARAMETERLIBRARY_BRAND, param_brand);
248 char param_grade[VP_MAX_LENGTH] = "";
249 VP_GetEnv(VP_VEHICLEPARAMETERLIBRARY_GRADE, param_grade);
251 bool is_match = false;
252 for (uint16_t i = 0; i < _countof(kDestinationTbl); i++) {
253 size_t area_size = static_cast<size_t>(std::string(kDestinationTbl[i].area).size());
254 // Check vehicle parameter settings (For VP_VEHICLEPARAMETERLIBRALY_AREA only, check the area size of tbl to check the character strings common to each area)
255 if ((strncmp(param_area, kDestinationTbl[i].area, area_size) == 0) &&
256 (strncmp(param_brand, kDestinationTbl[i].brand, sizeof(param_area)) == 0) &&
257 (strncmp(param_grade, kDestinationTbl[i].grade, sizeof(param_area)) == 0)) {
259 snprintf(path, BKUP_XML_PATH_MAX, "%s%s%s%s", BKUP_XML_PATH, BKUP_XML_PREFIX,
260 kDestinationTbl[i].destination, BKUP_XML_EXTENSION);
264 if (is_match == false) {
265 // If the destination settings do not match, set the AREA2_T path as failsafe
266 snprintf(path, BKUP_XML_PATH_MAX, "%s%s%s%s", BKUP_XML_PATH, BKUP_XML_PREFIX,
267 BKUP_DESTINATION_TYPE_AREA2_T, BKUP_XML_EXTENSION);
268 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Unexpected VP area[%s] brand[%s] grade[%s]",
269 param_area, param_brand, param_grade);
274 int BckupParamInit(void) {
276 xmlParserCtxtPtr xmlctx;
284 g_backup_params = new BackupParams; // LCOV_EXCL_BR_LINE 11:except,C++ operator
286 LIBXML_TEST_VERSION // LCOV_EXCL_BR_LINE 11:unexpected branch
287 // LCOV_EXCL_BR_START 11:unexpected branch
288 xmlInitParser(); // NOLINT(readability/nolint) Defined in library of libxml
289 // LCOV_EXCL_BR_STOP 11:unexpected branch
291 memset(&saxh, 0, sizeof(saxh));
292 saxh.initialized = XML_SAX2_MAGIC;
293 saxh.startElementNs = StartElementNs;
295 xmlctx = xmlCreatePushParserCtxt(&saxh, g_backup_params, NULL, 0, NULL); // LCOV_EXCL_BR_LINE 11:unexpected branch
297 char xml_path[BKUP_XML_PATH_MAX] = {0};
298 ret = BkupGetXmlPath(xml_path);
299 if (ret != 0) { // LCOV_EXCL_BR_LINE 6:Excluded because the return value does not cause an error
300 // LCOV_EXCL_START 6:Excluded because the return value does not cause an error
301 AGL_ASSERT_NOT_TESTED();
302 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "BkupGetXmlPath Error");
304 // LCOV_EXCL_STOP 6:Excluded because the return value does not cause an error
307 if ((fd = open(xml_path, O_RDONLY)) < 0) { // LCOV_EXCL_BR_LINE 5:open's error case.
308 // LCOV_EXCL_START 5:open's error case.
309 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
310 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "open:%s", strerror(errno));
312 // LCOV_EXCL_STOP 5:open's error case.
314 if (fstat(fd, &sb) < 0) { // LCOV_EXCL_BR_LINE 5:fstat's error case.
315 // LCOV_EXCL_START 5:fstat's error case.
316 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
317 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "fstat:%s", strerror(errno));
319 // LCOV_EXCL_STOP 5:fstat's error case.
321 map = reinterpret_cast<char *>(mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
322 if (map == MAP_FAILED) { // LCOV_EXCL_BR_LINE 5:mmap's error case.
323 // LCOV_EXCL_START 5:mmap's error case.
324 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
325 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "mmap:%s", strerror(errno));
327 // LCOV_EXCL_STOP 5:mmap's error case.
330 start = BkupTimerReal();
331 if (xmlParseChunk(xmlctx, map, static_cast<int>(sb.st_size), 1)) { // LCOV_EXCL_BR_LINE 5:xmlParseChunk's error case.
332 // LCOV_EXCL_START 5:xmlParseChunk's error case.
333 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
334 xmlParserError(xmlctx, "xmlParseChunk");
336 // LCOV_EXCL_STOP 5:xmlParseChunk's error case.
338 end = BkupTimerReal();
339 // LCOV_EXCL_BR_START 15:marco defined in "native_service/ns_logger_if.h"
340 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __func__, "spent:%" PRIu64 ".%06" PRIu64 "ms",
341 static_cast<uint64_t>((end - start) / 1000000),
342 static_cast<uint64_t>((end - start) % 1000000));
343 // LCOV_EXCL_BR_STOP 15:marco defined in "native_service/ns_logger_if.h"
346 xmlFreeParserCtxt(xmlctx); // LCOV_EXCL_BR_LINE 11:unexpected branch
347 xmlFreeDoc(doc); // LCOV_EXCL_BR_LINE 11:unexpected branch
348 xmlCleanupParser(); // LCOV_EXCL_BR_LINE 11:unexpected branch
352 if (fd >= 0) { // LCOV_EXCL_BR_LINE 5:open's error case.
353 if (close(fd) < 0) { // LCOV_EXCL_BR_LINE 5:close's error case.
354 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
355 FRAMEWORKUNIFIEDLOG(ZONE_ERR, "close:%s", strerror(errno)); // LCOV_EXCL_LINE 5:close's error case.
358 if (map) { // LCOV_EXCL_BR_LINE 5:mmap's error case.
359 if (munmap(map, sb.st_size) < 0) { // LCOV_EXCL_BR_LINE 5:munmap's error case.
360 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
361 FRAMEWORKUNIFIEDLOG(ZONE_ERR, "munmap:%s", strerror(errno)); // LCOV_EXCL_LINE 5:munmap's error case.
367 int BkupParamGet(const char *item_name, bkup_query_result_t *result) {
368 if (g_backup_params == NULL) { // LCOV_EXCL_BR_LINE 6:g_backup_params will not be NULL
369 // LCOV_EXCL_START 6:g_backup_params will not be NULL
370 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
371 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Uninitialize call");
373 // LCOV_EXCL_STOP 6:g_backup_params will not be NULL
375 if (result == NULL) {
376 FRAMEWORKUNIFIEDLOG(ZONE_NS_ERR, __func__, "result is NULL");
379 ItemTable::iterator item_it = g_backup_params->item_table.find(item_name); // LCOV_EXCL_BR_LINE 11:except,C++ STL
380 if (item_it == g_backup_params->item_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL
384 // LCOV_EXCL_BR_START 11:except,C++ STL
385 CategoryTable::iterator category_it = g_backup_params->category_table.find(item_it->second.category);
386 // LCOV_EXCL_BR_STOP 11:except,C++ STL
387 if (category_it == g_backup_params->category_table.end()) { // LCOV_EXCL_BR_LINE 6:double check
388 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
389 return -1; // LCOV_EXCL_LINE 6:double check
392 // LCOV_EXCL_BR_START 11:except,C++ STL
393 result->id = item_it->second.id;
394 result->size = item_it->second.size;
395 result->opt = item_it->second.opt;
396 result->nand = category_it->second.nand;
397 result->cache_dram = category_it->second.cache_dram;
398 result->backup_dram = category_it->second.backup_dram;
399 result->sync = category_it->second.sync;
400 result->encrypt = category_it->second.encrypt;
401 result->backup_cycle = category_it->second.backup_cycle;
402 BkupStrlcpy(result->category_name, item_it->second.category.c_str(), sizeof(result->category_name));
403 // LCOV_EXCL_BR_STOP 11:except,C++ STL
408 int BkupParamGetNumid(uint32_t num_id, bkup_query_result_t *result,
409 char *item_name, size_t item_name_size) {
410 if (g_backup_params == NULL) { // LCOV_EXCL_BR_LINE 6:g_backup_params will not be NULL
411 // LCOV_EXCL_START 6:g_backup_params will not be NULL
412 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
413 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Uninitialize call");
415 // LCOV_EXCL_STOP 6:g_backup_params will not be NULL
418 // LCOV_EXCL_BR_START 11:except,C++ STL
419 IdTable::iterator id_it = g_backup_params->id_table.find(static_cast<int>(num_id));
420 // LCOV_EXCL_BR_STOP 11:except,C++ STL
421 if (id_it == g_backup_params->id_table.end()) { // LCOV_EXCL_BR_LINE 11:except,C++ STL
424 BkupStrlcpy(item_name, id_it->second.c_str(), item_name_size); // LCOV_EXCL_BR_LINE 11:except,C++ STL
426 return BkupParamGet(id_it->second.c_str(), result); // LCOV_EXCL_BR_LINE 11:except,C++ STL
429 void *BkupParamSetOpt(const char *item_name, void *opt) {
430 if (g_backup_params == NULL) { // LCOV_EXCL_BR_LINE 6:g_backup_params will not be NULL
431 // LCOV_EXCL_START 6:g_backup_params will not be NULL
432 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
433 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "Uninitialize call");
434 return reinterpret_cast<void *>((-1));
435 // LCOV_EXCL_STOP 6:g_backup_params will not be NULL
438 ItemTable::iterator item_it = g_backup_params->item_table.find(item_name); // LCOV_EXCL_BR_LINE 11:except,C++ STL
439 if (item_it == g_backup_params->item_table.end()) { // LCOV_EXCL_BR_LINE 6:double check
440 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
441 return reinterpret_cast<void *>((-1)); // LCOV_EXCL_LINE 6:double check
444 // LCOV_EXCL_BR_START 11:unexpected branch
445 return __sync_val_compare_and_swap(&item_it->second.opt, NULL, opt); // NOLINT(readability/nolint) Supplied by gcc
446 // LCOV_EXCL_BR_STOP 11:unexpected branch