Line data Source code
1 : /**
2 : * Copyright (C) 2013 - 2015 Advanced Driver Information Technology.
3 : * This code is developed by Advanced Driver Information Technology.
4 : * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
5 : *
6 : * DLT offline log storage functionality source file.
7 : *
8 : * \copyright
9 : * This Source Code Form is subject to the terms of the
10 : * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
11 : * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 : *
13 : *
14 : * \author Syed Hameed <shameed@jp.adit-jv.com> ADIT 2013 - 2015
15 : * \author Christoph Lipka <clipka@jp.adit-jv.com> ADIT 2015
16 : *
17 : * \file: dlt_offline_logstorage.c
18 : * For further information see http://www.covesa.org/.
19 : */
20 : #include <stdio.h>
21 : #include <string.h>
22 : #include <stdlib.h>
23 : #include <limits.h>
24 : #include <ctype.h>
25 : #include <syslog.h>
26 : #include <sys/stat.h>
27 : #include <sys/stat.h>
28 : #include <unistd.h>
29 : #include <dirent.h>
30 : #include <time.h>
31 :
32 : #include "dlt_offline_logstorage.h"
33 : #include "dlt_offline_logstorage_internal.h"
34 : #include "dlt_offline_logstorage_behavior.h"
35 : #include "dlt_config_file_parser.h"
36 :
37 : #define DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR 1
38 : #define DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR 2
39 : #define DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE 3
40 :
41 : #define GENERAL_BASE_NAME "General"
42 :
43 35 : DLT_STATIC void dlt_logstorage_filter_config_free(DltLogStorageFilterConfig* data)
44 : {
45 : DltLogStorageFileList* n = NULL;
46 : DltLogStorageFileList* n1 = NULL;
47 :
48 35 : if (data->apids) {
49 32 : free(data->apids);
50 32 : data->apids = NULL;
51 : }
52 :
53 35 : if (data->ctids) {
54 32 : free(data->ctids);
55 32 : data->ctids = NULL;
56 : }
57 :
58 35 : if (data->excluded_apids) {
59 0 : free(data->excluded_apids);
60 0 : data->excluded_apids = NULL;
61 : }
62 :
63 35 : if (data->excluded_ctids) {
64 0 : free(data->excluded_ctids);
65 0 : data->excluded_ctids = NULL;
66 : }
67 :
68 35 : if (data->file_name) {
69 30 : free(data->file_name);
70 30 : data->file_name = NULL;
71 : }
72 :
73 35 : if (data->working_file_name) {
74 12 : free(data->working_file_name);
75 12 : data->working_file_name = NULL;
76 : }
77 :
78 35 : if (data->ecuid != NULL) {
79 24 : free(data->ecuid);
80 24 : data->ecuid = NULL;
81 : }
82 :
83 35 : if (data->log != NULL)
84 1 : fclose(data->log);
85 :
86 : #ifdef DLT_LOGSTORAGE_USE_GZIP
87 : if (data->gzlog != NULL)
88 : gzclose(data->gzlog);
89 : #endif
90 :
91 35 : if (data->cache != NULL) {
92 10 : free(data->cache);
93 10 : data->cache = NULL;
94 : }
95 :
96 35 : n = data->records;
97 :
98 54 : while (n) {
99 : n1 = n;
100 19 : n = n->next;
101 19 : if (n1->name) {
102 19 : free(n1->name);
103 : n1->name = NULL;
104 : }
105 :
106 19 : free(n1);
107 : n1 = NULL;
108 : }
109 35 : }
110 :
111 : /**
112 : * dlt_logstorage_list_destroy
113 : *
114 : * Destroy Filter configurations list.
115 : *
116 : * @param list List of the filter configurations will be destroyed.
117 : * @param uconfig User configurations for log file
118 : * @param dev_path Path to the device
119 : * @param reason Reason for the destroying of Filter configurations list
120 : * @return 0 on success, -1 on error
121 : */
122 8 : DLT_STATIC int dlt_logstorage_list_destroy(
123 : DltLogStorageFilterList** list, DltLogStorageUserConfig* uconfig, char* dev_path, int reason)
124 : {
125 : DltLogStorageFilterList* tmp = NULL;
126 :
127 27 : while (*(list) != NULL) {
128 : tmp = *list;
129 19 : *list = (*list)->next;
130 19 : if (tmp->key_list != NULL) {
131 19 : free(tmp->key_list);
132 19 : tmp->key_list = NULL;
133 : }
134 :
135 19 : if (tmp->data != NULL) {
136 : /* sync data if necessary */
137 : /* ignore return value */
138 19 : tmp->data->dlt_logstorage_sync(tmp->data, uconfig, dev_path, reason);
139 :
140 19 : dlt_logstorage_filter_config_free(tmp->data);
141 :
142 19 : free(tmp->data);
143 : tmp->data = NULL;
144 : }
145 :
146 19 : free(tmp);
147 : tmp = NULL;
148 : }
149 :
150 8 : return 0;
151 : }
152 :
153 63 : DLT_STATIC int dlt_logstorage_list_add_config(DltLogStorageFilterConfig* data, DltLogStorageFilterConfig** listdata)
154 : {
155 63 : if (*(listdata) == NULL)
156 : return -1;
157 :
158 : /* copy the data to list */
159 : memcpy(*listdata, data, sizeof(DltLogStorageFilterConfig));
160 :
161 63 : if (data->apids != NULL)
162 58 : (*listdata)->apids = strdup(data->apids);
163 :
164 63 : if (data->ctids != NULL)
165 58 : (*listdata)->ctids = strdup(data->ctids);
166 :
167 63 : if (data->excluded_apids != NULL)
168 12 : (*listdata)->excluded_apids = strdup(data->excluded_apids);
169 :
170 63 : if (data->excluded_ctids != NULL)
171 12 : (*listdata)->excluded_ctids = strdup(data->excluded_ctids);
172 :
173 63 : if (data->file_name != NULL)
174 56 : (*listdata)->file_name = strdup(data->file_name);
175 :
176 63 : if (data->ecuid != NULL)
177 52 : (*listdata)->ecuid = strdup(data->ecuid);
178 :
179 : return 0;
180 : }
181 :
182 : /**
183 : * dlt_logstorage_list_add
184 : *
185 : * Add Filter configurations to the list.
186 : *
187 : * @param keys Keys will be added to the list.
188 : * @param num_keys Number of keys
189 : * @param data Filter configurations data will be added to the list.
190 : * @param list List of the filter configurations
191 : * @return 0 on success, -1 on error
192 : */
193 62 : DLT_STATIC int dlt_logstorage_list_add(
194 : char* keys, int num_keys, DltLogStorageFilterConfig* data, DltLogStorageFilterList** list)
195 : {
196 : DltLogStorageFilterList* tmp = NULL;
197 :
198 164 : while (*(list) != NULL) {
199 102 : list = &(*list)->next;
200 : }
201 :
202 62 : tmp = (DltLogStorageFilterList*)calloc(1, sizeof(DltLogStorageFilterList));
203 :
204 62 : if (tmp == NULL)
205 : return -1;
206 :
207 62 : tmp->key_list = (char*)calloc((size_t)num_keys * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN, sizeof(char));
208 62 : if (tmp->key_list == NULL) {
209 0 : free(tmp);
210 : tmp = NULL;
211 0 : return -1;
212 : }
213 :
214 : memcpy(tmp->key_list, keys, (size_t)num_keys * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN);
215 62 : tmp->num_keys = num_keys;
216 62 : tmp->next = NULL;
217 62 : tmp->data = (DltLogStorageFilterConfig*)calloc(1, sizeof(DltLogStorageFilterConfig));
218 :
219 62 : if (tmp->data == NULL) {
220 0 : free(tmp->key_list);
221 : tmp->key_list = NULL;
222 0 : free(tmp);
223 : tmp = NULL;
224 0 : return -1;
225 : }
226 :
227 62 : if (dlt_logstorage_list_add_config(data, &(tmp->data)) != 0) {
228 0 : free(tmp->key_list);
229 : tmp->key_list = NULL;
230 0 : free(tmp->data);
231 : tmp->data = NULL;
232 0 : free(tmp);
233 : tmp = NULL;
234 0 : return -1;
235 : }
236 :
237 62 : *list = tmp;
238 :
239 62 : return 0;
240 : }
241 :
242 : /**
243 : * dlt_logstorage_list_find
244 : *
245 : * Find all Filter configurations corresponding with key provided.
246 : *
247 : * @param key Key to find the filter configurations
248 : * @param list List of the filter configurations
249 : * @param config Filter configurations corresponding with the key.
250 : * @return Number of the filter configuration found.
251 : */
252 3229 : DLT_STATIC int dlt_logstorage_list_find(char* key, DltLogStorageFilterList** list, DltLogStorageFilterConfig** config)
253 : {
254 : int i = 0;
255 : int num = 0;
256 :
257 41230 : while (*(list) != NULL) {
258 75511 : for (i = 0; i < (*list)->num_keys; i++) {
259 38001 : if (strncmp(
260 38001 : ((*list)->key_list + (i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)), key,
261 : DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)
262 : == 0) {
263 491 : config[num] = (*list)->data;
264 491 : num++;
265 491 : break;
266 : }
267 : }
268 38001 : list = &(*list)->next;
269 : }
270 :
271 3229 : return num;
272 : }
273 :
274 : /* Configuration file parsing helper functions */
275 :
276 19 : DLT_STATIC int dlt_logstorage_count_ids(const char* str)
277 : {
278 19 : if (str == NULL)
279 : return -1;
280 :
281 : /* delimiter is: "," */
282 : const char* p = str;
283 : int i = 0;
284 : int num = 1;
285 :
286 200 : while (p[i] != 0) {
287 162 : if (p[i] == ',')
288 18 : num++;
289 :
290 162 : i++;
291 : }
292 :
293 : return num;
294 : }
295 :
296 : /**
297 : * dlt_logstorage_free
298 : *
299 : * Free all allocated memory used in log storage handle
300 : *
301 : * @param handle DLT Logstorage handle
302 : * @param reason Reason for freeing the device
303 : *
304 : */
305 2 : void dlt_logstorage_free(DltLogStorage* handle, int reason)
306 : {
307 2 : if (handle == NULL) {
308 0 : dlt_vlog(LOG_ERR, "%s failed: handle is NULL\n", __func__);
309 0 : return;
310 : }
311 :
312 2 : dlt_logstorage_list_destroy(&(handle->config_list), &handle->uconfig, handle->device_mount_point, reason);
313 : }
314 :
315 :
316 : /**
317 : * dlt_logstorage_read_list_of_names
318 : *
319 : * Evaluate app and ctx names given in config file and create a list of names
320 : * acceptable by DLT Daemon. When using SET_APPLICATION_NAME and SET_CONTEXT_NAME
321 : * there is no constraint that these names have max 4 characters. Internally,
322 : * these names are cutted down to max 4 chars. To have create valid keys, the
323 : * internal representation of these names has to be considered.
324 : * Therefore, a given configuration of "AppLogName = App1,Application2,A3" will
325 : * be stored as "App1,Appl,A3".
326 : *
327 : * @param names to store the list of names
328 : * @param value string given in config file
329 : * @return 0 on success, -1 on error
330 : */
331 38 : DLT_STATIC int dlt_logstorage_read_list_of_names(char** names, const char* value)
332 : {
333 : int i = 0;
334 : int y = 0;
335 : size_t len = 0;
336 : char* tok;
337 : int num = 1;
338 :
339 38 : if ((names == NULL) || (value == NULL)) {
340 1 : dlt_vlog(LOG_ERR, "%s: Arguments are set to NULL\n", __func__);
341 1 : return -1;
342 : }
343 :
344 : /* free, alloce'd memory to store new apid/ctid */
345 37 : if (*names != NULL) {
346 5 : free(*names);
347 5 : *names = NULL;
348 : }
349 :
350 37 : len = strlen(value);
351 :
352 37 : if (len == 0) {
353 0 : dlt_vlog(LOG_ERR, "%s: Length of string given in config file is 0\n", __func__);
354 0 : return -1;
355 : }
356 :
357 : /* count number of delimiters to get actual number off names */
358 13 : num = dlt_logstorage_count_ids(value);
359 :
360 : /* need to alloc space for 5 chars, 4 for the name and "," and "\0" */
361 37 : *names = (char*)calloc((size_t)num * 5, sizeof(char));
362 :
363 37 : if (*names == NULL) {
364 0 : dlt_vlog(LOG_ERR, "%s: Cannot allocate memory\n", __func__);
365 0 : return -1;
366 : }
367 :
368 :
369 37 : char* tok_buf = strdup(value);
370 : char* tok_ptr = tok_buf;
371 37 : tok = strtok(tok_ptr, ",");
372 :
373 : i = 1;
374 :
375 :
376 89 : while (tok != NULL) {
377 52 : len = strlen(tok);
378 52 : len = DLT_OFFLINE_LOGSTORAGE_MIN(len, 4);
379 :
380 52 : int written = snprintf((*names + y), 5, "%.*s", (int)len, tok);
381 52 : if (written > 0 && written < 5) {
382 52 : if ((num > 1) && (i < num)) {
383 15 : (*names)[y + written] = ',';
384 15 : (*names)[y + written + 1] = '\0';
385 : }
386 52 : y += written + 1;
387 : } else {
388 : /* snprintf failed or truncated, do not advance y */
389 : break;
390 : }
391 52 : i++;
392 52 : tok = strtok(NULL, ",");
393 : }
394 :
395 37 : free(tok_buf);
396 :
397 37 : return 0;
398 : }
399 :
400 12 : DLT_STATIC int dlt_logstorage_set_number(unsigned int* number, unsigned int value)
401 : {
402 12 : if (value == 0) {
403 0 : dlt_log(LOG_ERR, "Invalid value of 0\n");
404 0 : return -1;
405 : }
406 :
407 38 : *number = value;
408 :
409 38 : return 0;
410 : }
411 :
412 : /**
413 : * dlt_logstorage_read_number
414 : *
415 : * Evaluate file size and number of files given in config file and set file size
416 : * The file number is checked by converting a string to an unsigned integer
417 : * width 0 > result < UINT_MAX (excludes 0!)
418 : * Non-digit characters including spaces and out of boundary will lead to an
419 : * error -1.
420 : *
421 : * @param number Number to be read
422 : * @param value string given in config file
423 : * @return 0 on success, -1 on error
424 : */
425 39 : DLT_STATIC int dlt_logstorage_read_number(unsigned int* number, char* value)
426 : {
427 : size_t i = 0;
428 : size_t len = 0;
429 : unsigned long size = 0;
430 :
431 39 : if (value == NULL)
432 : return -1;
433 :
434 38 : *number = 0;
435 38 : len = strlen(value);
436 :
437 : /* check if string consists of digits only */
438 148 : for (i = 0; i < len; i++)
439 110 : if (!isdigit((unsigned char)value[i])) {
440 0 : dlt_log(LOG_ERR, "Invalid, is not a number \n");
441 0 : return -1;
442 : }
443 :
444 38 : size = strtoul(value, NULL, 10);
445 38 : if (size > UINT_MAX) {
446 0 : dlt_log(LOG_ERR, "Value out of range for unsigned int\n");
447 0 : return -1;
448 : }
449 38 : return dlt_logstorage_set_number(number, (unsigned int)size);
450 : }
451 :
452 : /**
453 : * dlt_logstorage_get_keys_list
454 : *
455 : * Obtain key list and number of keys for id list passed
456 : * after splitting it between seperator (,)
457 : *
458 : * @param ids ID's
459 : * @param sep Seperator
460 : * @param list Prepared key list is stored here
461 : * @param numids Number of keys in the list is stored here
462 : * @return: 0 on success, error on failure*
463 : */
464 36 : DLT_STATIC int dlt_logstorage_get_keys_list(char* ids, char* sep, char** list, int* numids)
465 : {
466 : char* token = NULL;
467 36 : char* tmp_token = NULL;
468 : char* ids_local = NULL;
469 :
470 36 : *numids = 0;
471 :
472 : /* Duplicate the ids passed for using in strtok_r() */
473 36 : ids_local = strdup(ids);
474 :
475 36 : if (ids_local == NULL)
476 : return -1;
477 :
478 36 : token = strtok_r(ids_local, sep, &tmp_token);
479 :
480 36 : if (token == NULL) {
481 0 : free(ids_local);
482 0 : return -1;
483 : }
484 :
485 36 : *list = (char*)calloc((size_t)DLT_OFFLINE_LOGSTORAGE_MAXIDS * (DLT_ID_SIZE + 1), sizeof(char));
486 :
487 36 : if (*(list) == NULL) {
488 0 : free(ids_local);
489 0 : return -1;
490 : }
491 :
492 72 : while (token != NULL) {
493 : /* If it reached the max then other ids are ignored */
494 36 : if (*numids >= DLT_OFFLINE_LOGSTORAGE_MAXIDS) {
495 0 : free(ids_local);
496 0 : return 0;
497 : }
498 :
499 36 : snprintf(((*list) + ((*numids) * (DLT_ID_SIZE + 1))), DLT_ID_SIZE + 1, "%.*s", DLT_ID_SIZE, token);
500 36 : *numids = *numids + 1;
501 36 : token = strtok_r(NULL, sep, &tmp_token);
502 : }
503 :
504 36 : free(ids_local);
505 :
506 36 : return 0;
507 : }
508 :
509 24 : DLT_STATIC bool dlt_logstorage_check_excluded_ids(char* id, char* delim, char* excluded_ids)
510 : {
511 : char* token = NULL;
512 24 : char* tmp_token = NULL;
513 : char* ids_local = NULL;
514 :
515 24 : if ((id == NULL) || (delim == NULL) || (excluded_ids == NULL)) {
516 1 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
517 1 : return false;
518 : }
519 :
520 23 : ids_local = strdup(excluded_ids);
521 :
522 23 : if (ids_local == NULL) {
523 0 : dlt_vlog(LOG_ERR, "%s: Cannot duplicate string.\n", __func__);
524 0 : return false;
525 : }
526 :
527 23 : token = strtok_r(ids_local, delim, &tmp_token);
528 :
529 23 : if (token == NULL) {
530 0 : dlt_vlog(LOG_ERR, "%s: %s could not be parsed.\n", __func__, ids_local);
531 0 : free(ids_local);
532 0 : return false;
533 : }
534 :
535 39 : while (token != NULL) {
536 29 : if (strncmp(id, token, DLT_ID_SIZE) == 0) {
537 13 : free(ids_local);
538 13 : return true;
539 : }
540 :
541 16 : token = strtok_r(NULL, delim, &tmp_token);
542 : }
543 :
544 10 : free(ids_local);
545 10 : return false;
546 : }
547 :
548 : /**
549 : * dlt_logstorage_create_keys_only_ctid
550 : *
551 : * Prepares keys with context ID alone, will use ecuid if provided
552 : * (ecuid\:\:ctid) or (\:\:ctid)
553 : *
554 : * @param ecuid ECU ID
555 : * @param ctid Context ID
556 : * @param key Prepared key stored here
557 : * @return None
558 : */
559 0 : DLT_STATIC void dlt_logstorage_create_keys_only_ctid(char* ecuid, char* ctid, char* key)
560 : {
561 0 : char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = {0};
562 : const char* delimiter = "::";
563 :
564 0 : if (ecuid != NULL) {
565 : snprintf(curr_str, sizeof(curr_str), "%.*s%s", DLT_ID_SIZE, ecuid, delimiter);
566 : } else {
567 : snprintf(curr_str, sizeof(curr_str), "%s", delimiter);
568 : }
569 0 : if (ctid != NULL) {
570 0 : strncat(curr_str, ctid, sizeof(curr_str) - strlen(curr_str) - 1);
571 : }
572 : snprintf(key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1, "%s", curr_str);
573 0 : }
574 :
575 : /**
576 : * dlt_logstorage_create_keys_only_apid
577 : *
578 : * Prepares keys with application ID alone, will use ecuid if provided
579 : * (ecuid:apid::) or (:apid::)
580 : *
581 : * @param ecuid ECU ID
582 : * @param apid Application ID
583 : * @param key Prepared key stored here
584 : * @return None
585 : */
586 4 : DLT_STATIC void dlt_logstorage_create_keys_only_apid(char* ecuid, char* apid, char* key)
587 : {
588 4 : char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = {0};
589 : const char* colon = ":";
590 :
591 4 : if (ecuid != NULL) {
592 : snprintf(curr_str, sizeof(curr_str), "%.*s%s", DLT_ID_SIZE, ecuid, colon);
593 : } else {
594 : snprintf(curr_str, sizeof(curr_str), "%s", colon);
595 : }
596 4 : if (apid != NULL) {
597 4 : strncat(curr_str, apid, sizeof(curr_str) - strlen(curr_str) - 1);
598 : }
599 4 : strncat(curr_str, colon, sizeof(curr_str) - strlen(curr_str) - 1);
600 : snprintf(key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1, "%s", curr_str);
601 4 : }
602 :
603 : /**
604 : * dlt_logstorage_create_keys_multi
605 : *
606 : * Prepares keys with apid, ctid (ecuid:apid:ctid), will use ecuid if is provided
607 : * (ecuid:apid:ctid) or (:apid:ctid)
608 : *
609 : * @param ecuid ECU ID
610 : * @param apid Application ID
611 : * @param ctid Context ID
612 : * @param key Prepared key stored here
613 : * @return None
614 : */
615 14 : DLT_STATIC void dlt_logstorage_create_keys_multi(char* ecuid, char* apid, char* ctid, char* key)
616 : {
617 14 : char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = {0};
618 : const char* colon = ":";
619 :
620 14 : if (ecuid != NULL) {
621 : snprintf(curr_str, sizeof(curr_str), "%.*s%s", DLT_ID_SIZE, ecuid, colon);
622 : } else {
623 : snprintf(curr_str, sizeof(curr_str), "%s", colon);
624 : }
625 14 : if (apid != NULL) {
626 14 : strncat(curr_str, apid, sizeof(curr_str) - strlen(curr_str) - 1);
627 : }
628 14 : strncat(curr_str, colon, sizeof(curr_str) - strlen(curr_str) - 1);
629 14 : if (ctid != NULL) {
630 14 : strncat(curr_str, ctid, sizeof(curr_str) - strlen(curr_str) - 1);
631 : }
632 : snprintf(key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1, "%s", curr_str);
633 14 : }
634 :
635 : /**
636 : * dlt_logstorage_create_keys_only_ecu
637 : *
638 : * Prepares keys with only ecuid (ecuid::)
639 : *
640 : * @param ecuid ECU ID
641 : * @param key Prepared key stored here
642 : * @return None
643 : */
644 0 : DLT_STATIC void dlt_logstorage_create_keys_only_ecu(char* ecuid, char* key)
645 : {
646 0 : char curr_str[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = {0};
647 :
648 : snprintf(curr_str, sizeof(curr_str), "%.*s::", DLT_ID_SIZE, ecuid);
649 : snprintf(key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1, "%s", curr_str);
650 0 : }
651 :
652 : /**
653 : * dlt_logstorage_create_keys
654 : *
655 : * Create keys for hash table
656 : *
657 : * From each section [filter] in offline logstorage configuration file, we
658 : * receive application and context id strings.
659 : * Application and context id can consist of
660 : * - a 4char long name
661 : * - a comma separated list of ids
662 : * - a wildcard: .*
663 : *
664 : * If both application and context id are set to wildcard, this will be treated
665 : * in the same way of the case application and context id are not present:
666 : * - EcuID must be specified
667 : *
668 : * If lists given for application and/or context id, all possible combinations
669 : * are returned as keys in a form "[apid][ctid], e.g. "APP1\:CTX1".
670 : * If wildcards are used, the non-wildcard value becomes the key, e.g. "APP1\:"
671 : * or "\:CTX2".
672 : *
673 : * @param[in] apids string given from filter configuration
674 : * @param[in] ctids string given from filter configuration
675 : * @param[in] ecuid string given from filter configuration
676 : * @param[out] keys keys to fill into hash table
677 : * @param[out] num_keys number of keys
678 : * @return: 0 on success, error on failure*
679 : */
680 18 : DLT_STATIC int dlt_logstorage_create_keys(char* apids, char* ctids, char* ecuid, char** keys, int* num_keys)
681 : {
682 : int i, j;
683 18 : int num_apids = 0;
684 18 : int num_ctids = 0;
685 18 : char* apid_list = NULL;
686 18 : char* ctid_list = NULL;
687 : char* curr_apid = NULL;
688 : char* curr_ctid = NULL;
689 18 : char curr_key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = {0};
690 : int num_currkey = 0;
691 :
692 : /* Handle ecuid alone case here */
693 18 : if (((apids == NULL) && (ctids == NULL) && (ecuid != NULL))
694 18 : || ((apids != NULL) && (strncmp(apids, ".*", 2) == 0) && (ctids != NULL) && (strncmp(ctids, ".*", 2) == 0)
695 : && (ecuid != NULL))) {
696 0 : dlt_logstorage_create_keys_only_ecu(ecuid, curr_key);
697 0 : *(num_keys) = 1;
698 0 : *(keys) = (char*)calloc((size_t)(*num_keys) * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN, sizeof(char));
699 :
700 0 : if (*(keys) == NULL)
701 : return -1;
702 :
703 : strncpy(*keys, curr_key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN - 1);
704 0 : (*keys)[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN - 1] = '\0';
705 0 : return 0;
706 : }
707 :
708 18 : if ((apids == NULL) || (ctids == NULL)) {
709 0 : dlt_log(LOG_ERR, "Required inputs (apid and ctid) are NULL\n");
710 0 : return -1;
711 : }
712 :
713 : /* obtain key list and number of keys for application ids */
714 18 : if (dlt_logstorage_get_keys_list(apids, ",", &apid_list, &num_apids) != 0) {
715 0 : dlt_log(LOG_ERR, "Failed to obtain apid, check configuration file \n");
716 0 : return -1;
717 : }
718 :
719 : /* obtain key list and number of keys for context ids */
720 18 : if (dlt_logstorage_get_keys_list(ctids, ",", &ctid_list, &num_ctids) != 0) {
721 0 : dlt_log(LOG_ERR, "Failed to obtain ctid, check configuration file \n");
722 0 : free(apid_list);
723 0 : return -1;
724 : }
725 :
726 18 : *(num_keys) = num_apids * num_ctids;
727 :
728 : /* allocate memory for needed number of keys */
729 18 : *(keys) = (char*)calloc((size_t)(*num_keys) * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN, sizeof(char));
730 :
731 18 : if (*(keys) == NULL) {
732 0 : free(apid_list);
733 0 : free(ctid_list);
734 0 : return -1;
735 : }
736 :
737 : /* store all combinations of apid ctid in keys */
738 36 : for (i = 0; i < num_apids; i++) {
739 18 : curr_apid = apid_list + (i * (DLT_ID_SIZE + 1));
740 :
741 36 : for (j = 0; j < num_ctids; j++) {
742 18 : curr_ctid = ctid_list + (j * (DLT_ID_SIZE + 1));
743 :
744 18 : if (strncmp(curr_apid, ".*", 2) == 0) /* only context id matters */
745 0 : dlt_logstorage_create_keys_only_ctid(ecuid, curr_ctid, curr_key);
746 18 : else if (strncmp(curr_ctid, ".*", 2) == 0) /* only app id matters*/
747 4 : dlt_logstorage_create_keys_only_apid(ecuid, curr_apid, curr_key);
748 : else /* key is combination of all */
749 14 : dlt_logstorage_create_keys_multi(ecuid, curr_apid, curr_ctid, curr_key);
750 :
751 : memcpy(
752 18 : (*keys + (num_currkey * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)), curr_key,
753 : DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN);
754 18 : (*keys + (num_currkey * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN))[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN - 1] = '\0';
755 18 : num_currkey += 1;
756 : memset(&curr_key[0], 0, sizeof(curr_key));
757 : }
758 : }
759 :
760 18 : free(apid_list);
761 18 : free(ctid_list);
762 :
763 18 : return 0;
764 : }
765 :
766 : /**
767 : * dlt_logstorage_prepare_table
768 : *
769 : * Prepares hash table with keys and data
770 : *
771 : * @param handle DLT Logstorage handle
772 : * @param data Holds all other configuration values
773 : * @return 0 on success, -1 on error
774 : */
775 18 : DLT_STATIC int dlt_logstorage_prepare_table(DltLogStorage* handle, DltLogStorageFilterConfig* data)
776 : {
777 : int ret = 0;
778 18 : int num_keys = 0;
779 : int found = 0;
780 18 : char* keys = NULL;
781 : DltNewestFileName* tmp = NULL;
782 : DltNewestFileName* prev_tmp = NULL;
783 : DltNewestFileName* new_tmp = NULL;
784 :
785 18 : if ((handle == NULL) || (data == NULL)) {
786 1 : dlt_vlog(LOG_ERR, "Invalid parameters in %s\n", __func__);
787 1 : return -1;
788 : }
789 :
790 17 : ret = dlt_logstorage_create_keys(data->apids, data->ctids, data->ecuid, &keys, &num_keys);
791 :
792 17 : if (ret != 0) {
793 0 : dlt_log(LOG_ERR, "Not able to create keys for hash table\n");
794 0 : return -1;
795 : }
796 :
797 : /* hash_add */
798 17 : if (dlt_logstorage_list_add(keys, num_keys, data, &(handle->config_list)) != 0) {
799 0 : dlt_log(LOG_ERR, "Adding to hash table failed, returning failure\n");
800 0 : dlt_logstorage_free(handle, DLT_LOGSTORAGE_SYNC_ON_ERROR);
801 0 : free(keys);
802 : keys = NULL;
803 0 : return -1;
804 : }
805 :
806 17 : if (data->file_name) {
807 16 : if (handle->newest_file_list != NULL) {
808 : tmp = handle->newest_file_list;
809 77 : while (tmp) {
810 66 : if (strcmp(tmp->file_name, data->file_name) == 0) {
811 : found = 1;
812 : break;
813 : } else {
814 : prev_tmp = tmp;
815 66 : tmp = tmp->next;
816 : }
817 : }
818 : }
819 :
820 11 : if (!found) {
821 16 : new_tmp = (DltNewestFileName*)calloc(1, sizeof(DltNewestFileName));
822 16 : if (new_tmp == NULL) {
823 : /* In this case, the existing list does not need to be freed.*/
824 0 : dlt_vlog(LOG_ERR, "Failed to allocate memory for new file name [%s]\n", data->file_name);
825 0 : free(keys);
826 : keys = NULL;
827 0 : return -1;
828 : }
829 16 : new_tmp->file_name = strdup(data->file_name);
830 16 : new_tmp->newest_file = NULL;
831 16 : new_tmp->next = NULL;
832 :
833 16 : if (handle->newest_file_list == NULL)
834 5 : handle->newest_file_list = new_tmp;
835 : else
836 11 : prev_tmp->next = new_tmp;
837 : }
838 : }
839 :
840 17 : free(keys);
841 : keys = NULL;
842 17 : return 0;
843 : }
844 :
845 : /**
846 : * dlt_logstorage_validate_filter_name
847 : *
848 : * Validates if the provided filter name is as required [FILTER<number>]
849 : *
850 : * @param name Filter name
851 : * @return 0 on success, -1 on error
852 : *
853 : */
854 18 : DLT_STATIC int dlt_logstorage_validate_filter_name(char* name)
855 : {
856 : size_t len = 0;
857 : int idx = 0;
858 : size_t config_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION);
859 : size_t storage_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION);
860 : size_t control_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION);
861 :
862 18 : if (name == NULL)
863 : return -1;
864 :
865 17 : len = strlen(name);
866 :
867 : /* Check if section header is of format "FILTER" followed by a number */
868 17 : if (strncmp(name, DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION, config_sec_len) == 0) {
869 22 : for (idx = (int)config_sec_len; (size_t)idx < len - 1; idx++)
870 5 : if (!isdigit((unsigned char)name[idx]))
871 : return -1;
872 : return 0;
873 0 : } else if (strncmp(name, DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION, storage_sec_len) == 0) {
874 0 : for (idx = (int)storage_sec_len; (size_t)idx < len - 1; idx++)
875 0 : if (!isdigit((unsigned char)name[idx]))
876 : return -1;
877 : return 0;
878 0 : } else if (strncmp(name, DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION, control_sec_len) == 0) {
879 0 : for (idx = (int)control_sec_len; (size_t)idx < len - 1; idx++)
880 0 : if (!isdigit((unsigned char)name[idx]))
881 : return -1;
882 : return 0;
883 : } else {
884 : return -1;
885 : }
886 : }
887 :
888 13 : DLT_STATIC void dlt_logstorage_filter_set_strategy(DltLogStorageFilterConfig* config, int strategy)
889 : {
890 13 : if (config == NULL)
891 : return;
892 :
893 : /* file based */
894 13 : if ((strategy == DLT_LOGSTORAGE_SYNC_ON_MSG) || (strategy == DLT_LOGSTORAGE_SYNC_UNSET)) {
895 14 : config->dlt_logstorage_prepare = &dlt_logstorage_prepare_on_msg;
896 14 : config->dlt_logstorage_write = &dlt_logstorage_write_on_msg;
897 14 : config->dlt_logstorage_sync = &dlt_logstorage_sync_on_msg;
898 : } else { /* cache based */
899 11 : config->dlt_logstorage_prepare = &dlt_logstorage_prepare_msg_cache;
900 11 : config->dlt_logstorage_write = &dlt_logstorage_write_msg_cache;
901 11 : config->dlt_logstorage_sync = &dlt_logstorage_sync_msg_cache;
902 : }
903 : }
904 :
905 18 : DLT_STATIC int dlt_logstorage_check_apids(DltLogStorageFilterConfig* config, char* value)
906 : {
907 18 : if ((config == NULL) || (value == NULL)) {
908 1 : dlt_log(LOG_ERR, "Not able to create keys for hash table\n");
909 1 : return -1;
910 : }
911 :
912 17 : return dlt_logstorage_read_list_of_names(&config->apids, value);
913 : }
914 :
915 18 : DLT_STATIC int dlt_logstorage_check_ctids(DltLogStorageFilterConfig* config, char* value)
916 : {
917 18 : if ((config == NULL) || (value == NULL))
918 : return -1;
919 :
920 17 : return dlt_logstorage_read_list_of_names(&config->ctids, (const char*)value);
921 : }
922 :
923 2 : DLT_STATIC int dlt_logstorage_store_config_excluded_apids(DltLogStorageFilterConfig* config, char* value)
924 : {
925 2 : if ((config == NULL) || (value == NULL)) {
926 1 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
927 1 : return -1;
928 : }
929 :
930 1 : return dlt_logstorage_read_list_of_names(&config->excluded_apids, value);
931 : }
932 :
933 2 : DLT_STATIC int dlt_logstorage_store_config_excluded_ctids(DltLogStorageFilterConfig* config, char* value)
934 : {
935 2 : if ((config == NULL) || (value == NULL)) {
936 1 : dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
937 1 : return -1;
938 : }
939 :
940 1 : return dlt_logstorage_read_list_of_names(&config->excluded_ctids, (const char*)value);
941 : }
942 :
943 5 : DLT_STATIC int dlt_logstorage_set_loglevel(int* log_level, int value)
944 : {
945 17 : *log_level = value;
946 17 : if ((value <= DLT_LOG_DEFAULT) || (value >= DLT_LOG_MAX)) {
947 0 : *log_level = -1;
948 0 : dlt_log(LOG_ERR, "Invalid log level \n");
949 0 : return -1;
950 : }
951 : return 0;
952 : }
953 :
954 18 : DLT_STATIC int dlt_logstorage_check_loglevel(DltLogStorageFilterConfig* config, char* value)
955 : {
956 : int ll = -1;
957 :
958 18 : if ((config == NULL) || (value == NULL)) {
959 1 : if (config != NULL)
960 0 : config->log_level = 0;
961 1 : dlt_vlog(LOG_ERR, "Invalid parameters in %s\n", __func__);
962 1 : return -1;
963 : }
964 :
965 17 : if (strcmp(value, "DLT_LOG_FATAL") == 0) {
966 : ll = 1;
967 16 : } else if (strcmp(value, "DLT_LOG_ERROR") == 0) {
968 : ll = 2;
969 12 : } else if (strcmp(value, "DLT_LOG_WARN") == 0) {
970 : ll = 3;
971 12 : } else if (strcmp(value, "DLT_LOG_INFO") == 0) {
972 : ll = 4;
973 0 : } else if (strcmp(value, "DLT_LOG_DEBUG") == 0) {
974 : ll = 5;
975 0 : } else if (strcmp(value, "DLT_LOG_VERBOSE") == 0) {
976 : ll = 6;
977 : }
978 :
979 5 : return dlt_logstorage_set_loglevel(&config->log_level, ll);
980 : }
981 :
982 0 : DLT_STATIC int dlt_logstorage_check_reset_loglevel(DltLogStorageFilterConfig* config, char* value)
983 : {
984 0 : if (config == NULL)
985 : return -1;
986 :
987 0 : if (value == NULL) {
988 0 : config->reset_log_level = 0;
989 0 : return -1;
990 : }
991 :
992 0 : if (strcmp(value, "DLT_LOG_OFF") == 0) {
993 0 : config->reset_log_level = DLT_LOG_OFF;
994 0 : } else if (strcmp(value, "DLT_LOG_FATAL") == 0) {
995 0 : config->reset_log_level = DLT_LOG_FATAL;
996 0 : } else if (strcmp(value, "DLT_LOG_ERROR") == 0) {
997 0 : config->reset_log_level = DLT_LOG_ERROR;
998 0 : } else if (strcmp(value, "DLT_LOG_WARN") == 0) {
999 0 : config->reset_log_level = DLT_LOG_WARN;
1000 0 : } else if (strcmp(value, "DLT_LOG_INFO") == 0) {
1001 0 : config->reset_log_level = DLT_LOG_INFO;
1002 0 : } else if (strcmp(value, "DLT_LOG_DEBUG") == 0) {
1003 0 : config->reset_log_level = DLT_LOG_DEBUG;
1004 0 : } else if (strcmp(value, "DLT_LOG_VERBOSE") == 0) {
1005 0 : config->reset_log_level = DLT_LOG_VERBOSE;
1006 : } else {
1007 0 : config->reset_log_level = -1;
1008 0 : dlt_log(LOG_ERR, "Invalid log level \n");
1009 0 : return -1;
1010 : }
1011 :
1012 : return 0;
1013 : }
1014 :
1015 19 : DLT_STATIC int dlt_logstorage_check_filename(DltLogStorageFilterConfig* config, char* value)
1016 : {
1017 : size_t len;
1018 :
1019 19 : if ((value == NULL) || (strcmp(value, "") == 0))
1020 : return -1;
1021 :
1022 18 : if (config->file_name != NULL) {
1023 2 : free(config->file_name);
1024 2 : config->file_name = NULL;
1025 : }
1026 :
1027 18 : len = strlen(value);
1028 :
1029 18 : if (len == 0) {
1030 0 : dlt_vlog(LOG_ERR, "%s: Length of string given in config file is 0\n", __func__);
1031 0 : return -1;
1032 : }
1033 :
1034 : /* do not allow the user to change directory by adding a relative path */
1035 18 : if (strstr(value, "..") == NULL) {
1036 17 : config->file_name = (char*)calloc(len + 1, sizeof(char));
1037 :
1038 17 : if (config->file_name == NULL) {
1039 0 : dlt_log(LOG_ERR, "Cannot allocate memory for filename\n");
1040 0 : return -1;
1041 : }
1042 :
1043 : memcpy(config->file_name, value, len);
1044 17 : config->file_name[len] = '\0';
1045 : } else {
1046 1 : dlt_log(LOG_ERR, "Invalid filename, paths not accepted due to security issues\n");
1047 1 : return -1;
1048 : }
1049 :
1050 17 : return 0;
1051 : }
1052 :
1053 19 : DLT_STATIC int dlt_logstorage_check_filesize(DltLogStorageFilterConfig* config, char* value)
1054 : {
1055 19 : if ((config == NULL) || (value == NULL))
1056 : return -1;
1057 :
1058 18 : return dlt_logstorage_read_number(&config->file_size, value);
1059 : }
1060 :
1061 18 : DLT_STATIC int dlt_logstorage_check_nofiles(DltLogStorageFilterConfig* config, char* value)
1062 : {
1063 18 : if ((config == NULL) || (value == NULL))
1064 : return -1;
1065 :
1066 17 : return dlt_logstorage_read_number(&config->num_files, value);
1067 : }
1068 :
1069 2 : DLT_STATIC int dlt_logstorage_check_specificsize(DltLogStorageFilterConfig* config, char* value)
1070 : {
1071 2 : if ((config == NULL) || (value == NULL))
1072 : return -1;
1073 :
1074 2 : return dlt_logstorage_read_number(&config->specific_size, value);
1075 : }
1076 :
1077 : /**
1078 : * dlt_logstorage_check_sync_strategy
1079 : *
1080 : * Evaluate sync strategy. The sync strategy is an optional filter
1081 : * configuration parameter.
1082 : * If the given value cannot be associated with a sync strategy, the default
1083 : * sync strategy will be assigned.
1084 : *
1085 : * @param config DltLogStorageFilterConfig
1086 : * @param value string given in config file
1087 : * @return 0 on success, -1 on error
1088 : */
1089 13 : DLT_STATIC int dlt_logstorage_check_sync_strategy(DltLogStorageFilterConfig* config, char* value)
1090 : {
1091 13 : if ((config == NULL) || (value == NULL))
1092 : return -1;
1093 :
1094 12 : if (strcasestr(value, "ON_MSG") != NULL) {
1095 1 : config->sync = DLT_LOGSTORAGE_SYNC_ON_MSG;
1096 1 : dlt_log(LOG_DEBUG, "ON_MSG found, ignore other if added\n");
1097 : } else { /* ON_MSG not set, combination of cache based strategies possible */
1098 :
1099 11 : if (strcasestr(value, "ON_DAEMON_EXIT") != NULL)
1100 4 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_DAEMON_EXIT;
1101 :
1102 11 : if (strcasestr(value, "ON_DEMAND") != NULL)
1103 2 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_DEMAND;
1104 :
1105 11 : if (strcasestr(value, "ON_DEVICE_DISCONNECT") != NULL)
1106 0 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT;
1107 :
1108 11 : if (strcasestr(value, "ON_SPECIFIC_SIZE") != NULL)
1109 2 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_SPECIFIC_SIZE;
1110 :
1111 11 : if (strcasestr(value, "ON_FILE_SIZE") != NULL)
1112 4 : config->sync |= DLT_LOGSTORAGE_SYNC_ON_FILE_SIZE;
1113 :
1114 11 : if (config->sync == 0) {
1115 1 : dlt_log(LOG_WARNING, "Unknown sync strategies. Set default ON_MSG\n");
1116 1 : config->sync = DLT_LOGSTORAGE_SYNC_ON_MSG;
1117 1 : return 1;
1118 : }
1119 : }
1120 :
1121 : return 0;
1122 : }
1123 :
1124 : /**
1125 : * dlt_logstorage_check_overwrite_strategy
1126 : *
1127 : * Evaluate overwrite strategy. The sync strategy is an optional filter
1128 : * configuration parameter.
1129 : * If the given value cannot be associated with a strategy, the default
1130 : * strategy will be assigned.
1131 : *
1132 : * @param[in] config DltLogStorageFilterConfig
1133 : * @param[in] value string given in config file
1134 : * @return 0 on success, 1 on unknown value, -1 on error
1135 : */
1136 12 : DLT_STATIC int dlt_logstorage_check_overwrite_strategy(DltLogStorageFilterConfig* config, char* value)
1137 : {
1138 12 : if ((config == NULL) || (value == NULL))
1139 : return -1;
1140 :
1141 12 : if (strcasestr(value, "DISCARD_OLD") != NULL) {
1142 6 : config->overwrite = DLT_LOGSTORAGE_OVERWRITE_DISCARD_OLD;
1143 6 : } else if (strcasestr(value, "DISCARD_NEW") != NULL) {
1144 6 : config->overwrite = DLT_LOGSTORAGE_OVERWRITE_DISCARD_NEW;
1145 : } else {
1146 0 : dlt_log(LOG_WARNING, "Unknown overwrite strategy. Set default DISCARD_OLD\n");
1147 0 : config->overwrite = DLT_LOGSTORAGE_OVERWRITE_DISCARD_OLD;
1148 0 : return 1;
1149 : }
1150 :
1151 : return 0;
1152 : }
1153 :
1154 : /**
1155 : * dlt_logstorage_check_disable_network
1156 : *
1157 : * Evaluate disable network. The disable network is an optional filter
1158 : * configuration parameter.
1159 : * If the given value cannot be associated with a flag, the default
1160 : * flag will be assigned.
1161 : *
1162 : * @param[in] config DltLogStorageFilterConfig
1163 : * @param[in] value string given in config file
1164 : * @return 0 on success, 1 on unknown value, -1 on error
1165 : */
1166 0 : DLT_STATIC int dlt_logstorage_check_disable_network(DltLogStorageFilterConfig* config, char* value)
1167 : {
1168 0 : if ((config == NULL) || (value == NULL))
1169 : return -1;
1170 :
1171 0 : if (strcasestr(value, "ON") != NULL) {
1172 0 : config->disable_network_routing = DLT_LOGSTORAGE_DISABLE_NW_ON;
1173 0 : } else if (strcasestr(value, "OFF") != NULL) {
1174 0 : config->disable_network_routing = DLT_LOGSTORAGE_DISABLE_NW_OFF;
1175 : } else {
1176 0 : dlt_log(LOG_WARNING, "Unknown disable network flag. Set default OFF\n");
1177 0 : config->disable_network_routing = DLT_LOGSTORAGE_DISABLE_NW_OFF;
1178 0 : return 1;
1179 : }
1180 :
1181 : return 0;
1182 : }
1183 :
1184 : /**
1185 : * dlt_logstorage_check_gzip_compression
1186 : *
1187 : * Evaluate gzip compression. The gzip compression is an optional filter
1188 : * configuration parameter.
1189 : * If the given value cannot be associated with a flag, the default
1190 : * flag will be assigned.
1191 : *
1192 : * @param[in] config DltLogStorageFilterConfig
1193 : * @param[in] value string given in config file
1194 : * @return 0 on success, 1 on unknown value, -1 on error
1195 : */
1196 0 : DLT_STATIC int dlt_logstorage_check_gzip_compression(DltLogStorageFilterConfig* config, char* value)
1197 : {
1198 : #ifdef DLT_LOGSTORAGE_USE_GZIP
1199 : if ((config == NULL) || (value == NULL))
1200 : return -1;
1201 :
1202 : if (strcasestr(value, "ON") != NULL) {
1203 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_ON;
1204 : } else if (strcasestr(value, "OFF") != NULL) {
1205 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_OFF;
1206 : } else {
1207 : dlt_log(LOG_WARNING, "Unknown gzip compression flag\n");
1208 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_ERROR;
1209 : return 1;
1210 : }
1211 : #else
1212 : (void)value;
1213 0 : dlt_log(LOG_WARNING, "dlt-daemon not compiled with logstorage gzip support\n");
1214 0 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_OFF;
1215 : #endif
1216 0 : return 0;
1217 : }
1218 :
1219 : /**
1220 : * dlt_logstorage_check_ecuid
1221 : *
1222 : * Evaluate if ECU idenfifier given in config file
1223 : *
1224 : * @param config DltLogStorageFilterConfig
1225 : * @param value string given in config file
1226 : * @return 0 on success, -1 on error
1227 : */
1228 14 : DLT_STATIC int dlt_logstorage_check_ecuid(DltLogStorageFilterConfig* config, char* value)
1229 : {
1230 : size_t len;
1231 :
1232 14 : if ((config == NULL) || (value == NULL) || (value[0] == '\0'))
1233 : return -1;
1234 :
1235 13 : if (config->ecuid != NULL) {
1236 1 : free(config->ecuid);
1237 1 : config->ecuid = NULL;
1238 : }
1239 :
1240 13 : len = strlen(value);
1241 13 : config->ecuid = (char*)calloc(len + 1, sizeof(char));
1242 :
1243 13 : if (config->ecuid == NULL)
1244 : return -1;
1245 :
1246 : memcpy(config->ecuid, value, len);
1247 13 : config->ecuid[len] = '\0';
1248 :
1249 13 : return 0;
1250 : }
1251 :
1252 : DLT_STATIC DltLogstorageFilterConf filter_cfg_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = {
1253 : [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = {.key = "LogAppName", .func = dlt_logstorage_check_apids, .is_opt = 1},
1254 : [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = {.key = "ContextName", .func = dlt_logstorage_check_ctids, .is_opt = 1},
1255 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_LOGAPPNAME] =
1256 : {.key = "ExcludedLogAppName", .func = dlt_logstorage_store_config_excluded_apids, .is_opt = 1},
1257 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_CONTEXTNAME] =
1258 : {.key = "ExcludedContextName", .func = dlt_logstorage_store_config_excluded_ctids, .is_opt = 1},
1259 : [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = {.key = "LogLevel", .func = dlt_logstorage_check_loglevel, .is_opt = 0},
1260 : [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] =
1261 : {.key = NULL, .func = dlt_logstorage_check_reset_loglevel, .is_opt = 0},
1262 : [DLT_LOGSTORAGE_FILTER_CONF_FILE] = {.key = "File", .func = dlt_logstorage_check_filename, .is_opt = 0},
1263 : [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = {.key = "FileSize", .func = dlt_logstorage_check_filesize, .is_opt = 0},
1264 : [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = {.key = "NOFiles", .func = dlt_logstorage_check_nofiles, .is_opt = 0},
1265 : [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] =
1266 : {.key = "SyncBehavior", .func = dlt_logstorage_check_sync_strategy, .is_opt = 1},
1267 : [DLT_LOGSTORAGE_FILTER_CONF_OVERWRITEBEHAVIOR] =
1268 : {.key = "OverwriteBehavior", .func = dlt_logstorage_check_overwrite_strategy, .is_opt = 1},
1269 : [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = {.key = "EcuID", .func = dlt_logstorage_check_ecuid, .is_opt = 1},
1270 : [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] =
1271 : {.key = "SpecificSize", .func = dlt_logstorage_check_specificsize, .is_opt = 1},
1272 : [DLT_LOGSTORAGE_FILTER_CONF_GZIP_COMPRESSION] =
1273 : {.key = "GzipCompression", .func = dlt_logstorage_check_gzip_compression, .is_opt = 1},
1274 : [DLT_LOGSTORAGE_FILTER_CONF_DISABLE_NETWORK] = {
1275 : .key = "DisableNetwork", .func = dlt_logstorage_check_disable_network, .is_opt = 1}};
1276 :
1277 : /* */
1278 : DLT_STATIC DltLogstorageFilterConf filter_nonverbose_storage_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = {
1279 : [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = {.key = NULL, .func = dlt_logstorage_check_apids, .is_opt = 0},
1280 : [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = {.key = NULL, .func = dlt_logstorage_check_ctids, .is_opt = 0},
1281 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_LOGAPPNAME] =
1282 : {.key = NULL, .func = dlt_logstorage_store_config_excluded_apids, .is_opt = 1},
1283 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_CONTEXTNAME] =
1284 : {.key = NULL, .func = dlt_logstorage_store_config_excluded_ctids, .is_opt = 1},
1285 : [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = {.key = NULL, .func = dlt_logstorage_check_loglevel, .is_opt = 0},
1286 : [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = {.key = NULL, .func = NULL, .is_opt = 0},
1287 : [DLT_LOGSTORAGE_FILTER_CONF_FILE] = {.key = "File", .func = dlt_logstorage_check_filename, .is_opt = 0},
1288 : [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = {.key = "FileSize", .func = dlt_logstorage_check_filesize, .is_opt = 0},
1289 : [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = {.key = "NOFiles", .func = dlt_logstorage_check_nofiles, .is_opt = 0},
1290 : [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = {.key = NULL, .func = dlt_logstorage_check_sync_strategy, .is_opt = 1},
1291 : [DLT_LOGSTORAGE_FILTER_CONF_OVERWRITEBEHAVIOR] =
1292 : {.key = NULL, .func = dlt_logstorage_check_overwrite_strategy, .is_opt = 1},
1293 : [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = {.key = "EcuID", .func = dlt_logstorage_check_ecuid, .is_opt = 0},
1294 : [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = {.key = NULL, .func = dlt_logstorage_check_specificsize, .is_opt = 1},
1295 : [DLT_LOGSTORAGE_FILTER_CONF_GZIP_COMPRESSION] =
1296 : {.key = "GzipCompression", .func = dlt_logstorage_check_gzip_compression, .is_opt = 1},
1297 : [DLT_LOGSTORAGE_FILTER_CONF_DISABLE_NETWORK] = {
1298 : .key = NULL, .func = dlt_logstorage_check_disable_network, .is_opt = 1}};
1299 :
1300 : DLT_STATIC DltLogstorageFilterConf filter_nonverbose_control_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = {
1301 : [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = {.key = "LogAppName", .func = dlt_logstorage_check_apids, .is_opt = 0},
1302 : [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = {.key = "ContextName", .func = dlt_logstorage_check_ctids, .is_opt = 0},
1303 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_LOGAPPNAME] =
1304 : {.key = NULL, .func = dlt_logstorage_store_config_excluded_apids, .is_opt = 1},
1305 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_CONTEXTNAME] =
1306 : {.key = NULL, .func = dlt_logstorage_store_config_excluded_ctids, .is_opt = 1},
1307 : [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = {.key = "LogLevel", .func = dlt_logstorage_check_loglevel, .is_opt = 0},
1308 : [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] =
1309 : {.key = "ResetLogLevel", .func = dlt_logstorage_check_reset_loglevel, .is_opt = 1},
1310 : [DLT_LOGSTORAGE_FILTER_CONF_FILE] = {.key = NULL, .func = dlt_logstorage_check_filename, .is_opt = 0},
1311 : [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = {.key = NULL, .func = dlt_logstorage_check_filesize, .is_opt = 0},
1312 : [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = {.key = NULL, .func = dlt_logstorage_check_nofiles, .is_opt = 0},
1313 : [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = {.key = NULL, .func = dlt_logstorage_check_sync_strategy, .is_opt = 1},
1314 : [DLT_LOGSTORAGE_FILTER_CONF_OVERWRITEBEHAVIOR] =
1315 : {.key = NULL, .func = dlt_logstorage_check_overwrite_strategy, .is_opt = 1},
1316 : [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = {.key = "EcuID", .func = dlt_logstorage_check_ecuid, .is_opt = 0},
1317 : [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = {.key = NULL, .func = dlt_logstorage_check_specificsize, .is_opt = 1},
1318 : [DLT_LOGSTORAGE_FILTER_CONF_GZIP_COMPRESSION] =
1319 : {.key = "GzipCompression", .func = dlt_logstorage_check_gzip_compression, .is_opt = 1},
1320 : [DLT_LOGSTORAGE_FILTER_CONF_DISABLE_NETWORK] = {
1321 : .key = NULL, .func = dlt_logstorage_check_disable_network, .is_opt = 1}};
1322 :
1323 : /**
1324 : * Check filter configuration parameter is valid.
1325 : *
1326 : * @param config DltLogStorageFilterConfig
1327 : * @param ctype DltLogstorageFilterConfType
1328 : * @param value specified property value from configuration file
1329 : * @return 0 on success, -1 otherwise
1330 : */
1331 26 : DLT_STATIC int dlt_logstorage_check_param(
1332 : DltLogStorageFilterConfig* config, DltLogstorageFilterConfType ctype, char* value)
1333 : {
1334 26 : if ((config == NULL) || (value == NULL))
1335 : return -1;
1336 :
1337 25 : if (ctype < DLT_LOGSTORAGE_FILTER_CONF_COUNT)
1338 25 : return filter_cfg_entries[ctype].func(config, value);
1339 :
1340 : return -1;
1341 : }
1342 :
1343 240 : DLT_STATIC int dlt_logstorage_get_filter_section_value(
1344 : DltConfigFile* config_file, char* sec_name, DltLogstorageFilterConf entry, char* value)
1345 : {
1346 : int ret = 0;
1347 :
1348 240 : if ((config_file == NULL) || (sec_name == NULL))
1349 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1350 :
1351 240 : if (entry.key != NULL) {
1352 224 : ret = dlt_config_file_get_value(config_file, sec_name, entry.key, value);
1353 :
1354 224 : if ((ret != 0) && (entry.is_opt == 0)) {
1355 0 : dlt_vlog(LOG_WARNING, "Invalid configuration in section: %s -> %s : %s\n", sec_name, entry.key, value);
1356 0 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1357 : }
1358 :
1359 92 : if ((ret != 0) && (entry.is_opt == 1)) {
1360 92 : dlt_vlog(LOG_DEBUG, "Optional parameter %s not specified\n", entry.key);
1361 92 : return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE;
1362 : }
1363 : } else {
1364 : return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE;
1365 : }
1366 :
1367 : return 0;
1368 : }
1369 :
1370 240 : DLT_STATIC int dlt_logstorage_get_filter_value(DltConfigFile* config_file, char* sec_name, int index, char* value)
1371 : {
1372 : int ret = 0;
1373 : size_t config_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION);
1374 : size_t storage_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION);
1375 : size_t control_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION);
1376 :
1377 240 : if ((config_file == NULL) || (sec_name == NULL))
1378 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1379 :
1380 : /* Branch based on section name, no complete string compare needed */
1381 240 : if (strncmp(sec_name, DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION, config_sec_len) == 0) {
1382 240 : ret = dlt_logstorage_get_filter_section_value(config_file, sec_name, filter_cfg_entries[index], value);
1383 0 : } else if (strncmp(sec_name, DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION, storage_sec_len) == 0) {
1384 0 : ret = dlt_logstorage_get_filter_section_value(
1385 : config_file, sec_name, filter_nonverbose_storage_entries[index], value);
1386 0 : } else if ((strncmp(sec_name, DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION, control_sec_len) == 0)) {
1387 0 : ret = dlt_logstorage_get_filter_section_value(
1388 : config_file, sec_name, filter_nonverbose_control_entries[index], value);
1389 : } else {
1390 0 : dlt_log(LOG_ERR, "Error: Section name not valid \n");
1391 : ret = DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1392 : }
1393 :
1394 : return ret;
1395 : }
1396 :
1397 16 : DLT_STATIC int dlt_logstorage_setup_table(DltLogStorage* handle, DltLogStorageFilterConfig* tmp_data)
1398 : {
1399 : int ret = 0;
1400 :
1401 : /* depending on the specified strategy set function pointers for
1402 : * prepare, write and sync */
1403 16 : dlt_logstorage_filter_set_strategy(tmp_data, tmp_data->sync);
1404 :
1405 16 : ret = dlt_logstorage_prepare_table(handle, tmp_data);
1406 :
1407 16 : if (ret != 0) {
1408 0 : dlt_vlog(LOG_ERR, "%s Error: Storing filter values failed\n", __func__);
1409 : ret = DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR;
1410 : }
1411 :
1412 16 : return ret;
1413 : }
1414 : /*Return :
1415 : * DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR - On filter properties or value is not valid
1416 : * DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR - On error while storing in hash table
1417 : */
1418 :
1419 16 : DLT_STATIC int dlt_daemon_offline_setup_filter_properties(
1420 : DltLogStorage* handle, DltConfigFile* config_file, char* sec_name)
1421 : {
1422 : DltLogStorageFilterConfig tmp_data;
1423 16 : char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN + 1] = {'\0'};
1424 : int i = 0;
1425 : int ret = 0;
1426 :
1427 16 : if ((handle == NULL) || (config_file == NULL) || (sec_name == NULL))
1428 : return DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR;
1429 :
1430 : memset(&tmp_data, 0, sizeof(DltLogStorageFilterConfig));
1431 16 : tmp_data.log_level = DLT_LOG_VERBOSE;
1432 : tmp_data.reset_log_level = DLT_LOG_OFF;
1433 16 : tmp_data.disable_network_routing = DLT_LOGSTORAGE_DISABLE_NW_OFF;
1434 :
1435 256 : for (i = 0; i < DLT_LOGSTORAGE_FILTER_CONF_COUNT; i++) {
1436 240 : ret = dlt_logstorage_get_filter_value(config_file, sec_name, i, value);
1437 :
1438 240 : if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR)
1439 : return ret;
1440 :
1441 240 : if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE)
1442 108 : continue;
1443 :
1444 : /* check value and store temporary */
1445 132 : ret = dlt_logstorage_check_param(&tmp_data, i, value);
1446 :
1447 132 : if (ret != 0) {
1448 0 : if (tmp_data.apids != NULL) {
1449 0 : free(tmp_data.apids);
1450 : tmp_data.apids = NULL;
1451 : }
1452 :
1453 0 : if (tmp_data.ctids != NULL) {
1454 0 : free(tmp_data.ctids);
1455 : tmp_data.ctids = NULL;
1456 : }
1457 :
1458 0 : if (tmp_data.excluded_apids != NULL) {
1459 0 : free(tmp_data.excluded_apids);
1460 : tmp_data.excluded_apids = NULL;
1461 : }
1462 :
1463 0 : if (tmp_data.excluded_ctids != NULL) {
1464 0 : free(tmp_data.excluded_ctids);
1465 : tmp_data.excluded_ctids = NULL;
1466 : }
1467 :
1468 0 : if (tmp_data.file_name != NULL) {
1469 0 : free(tmp_data.file_name);
1470 : tmp_data.file_name = NULL;
1471 : }
1472 :
1473 0 : if (tmp_data.working_file_name != NULL) {
1474 0 : free(tmp_data.working_file_name);
1475 : tmp_data.working_file_name = NULL;
1476 : }
1477 :
1478 0 : if (tmp_data.ecuid != NULL) {
1479 0 : free(tmp_data.ecuid);
1480 : tmp_data.ecuid = NULL;
1481 : }
1482 :
1483 0 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1484 : }
1485 : }
1486 :
1487 16 : if (dlt_logstorage_count_ids(tmp_data.excluded_apids) > 1
1488 0 : && dlt_logstorage_count_ids(tmp_data.excluded_ctids) > 1) {
1489 0 : dlt_vlog(
1490 : LOG_WARNING, "%s: Logstorage does not support both multiple excluded applications and contexts\n",
1491 : __func__);
1492 0 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1493 : }
1494 :
1495 : /* filter configuration is valid */
1496 16 : ret = dlt_logstorage_setup_table(handle, &tmp_data);
1497 :
1498 16 : if (ret != 0) {
1499 0 : dlt_vlog(LOG_ERR, "%s Error: Storing filter values failed\n", __func__);
1500 : ret = DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR;
1501 : } else { /* move to next free filter configuration, if no error occurred */
1502 16 : handle->num_configs += 1;
1503 : }
1504 :
1505 : /* free tmp_data */
1506 16 : dlt_logstorage_filter_config_free(&tmp_data);
1507 :
1508 16 : return ret;
1509 : }
1510 :
1511 : /**
1512 : * dlt_logstorage_check_maintain_logstorage_loglevel
1513 : *
1514 : * Evaluate to maintain the logstorage loglevel setting. This is an optional
1515 : * configuration parameter
1516 : * If the given value cannot be associated with an overwrite, the default value
1517 : * will be assigned.
1518 : *
1519 : * @param config DltLogStorage
1520 : * @param value string given in config file
1521 : * @return 0 on success, -1 on error
1522 : */
1523 0 : DLT_STATIC int dlt_logstorage_check_maintain_logstorage_loglevel(DltLogStorage* handle, char* value)
1524 : {
1525 0 : if ((handle == NULL) || (value == NULL)) {
1526 : return -1;
1527 : }
1528 :
1529 0 : if ((strncmp(value, "OFF", 3) == 0) || (strncmp(value, "0", 1) == 0)) {
1530 0 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF;
1531 0 : } else if ((strncmp(value, "ON", 2) == 0) || (strncmp(value, "1", 1) == 0)) {
1532 0 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_ON;
1533 : } else {
1534 0 : dlt_vlog(LOG_ERR, "Wrong value for Maintain logstorage loglevel section name: %s\n", value);
1535 0 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_ON;
1536 0 : return -1;
1537 : }
1538 :
1539 : return 0;
1540 : }
1541 :
1542 : DLT_STATIC DltLogstorageGeneralConf general_cfg_entries[DLT_LOGSTORAGE_GENERAL_CONF_COUNT] = {
1543 : [DLT_LOGSTORAGE_GENERAL_CONF_MAINTAIN_LOGSTORAGE_LOGLEVEL] = {
1544 : .key = "MaintainLogstorageLogLevel", .func = dlt_logstorage_check_maintain_logstorage_loglevel, .is_opt = 1}};
1545 :
1546 : /**
1547 : * Check if DltLogstorage General configuration parameter is valid.
1548 : *
1549 : * @param handle pointer to DltLogstorage structure
1550 : * @param ctype Logstorage general configuration type
1551 : * @param value specified property value from configuration file
1552 : * @return 0 on success, -1 otherwise
1553 : */
1554 0 : DLT_STATIC int dlt_logstorage_check_general_param(
1555 : DltLogStorage* handle, DltLogstorageGeneralConfType ctype, char* value)
1556 : {
1557 0 : if ((handle == NULL) || (value == NULL)) {
1558 : return -1;
1559 : }
1560 :
1561 0 : if (ctype < DLT_LOGSTORAGE_GENERAL_CONF_COUNT) {
1562 0 : return general_cfg_entries[ctype].func(handle, value);
1563 : }
1564 :
1565 : return -1;
1566 : }
1567 :
1568 0 : DLT_STATIC int dlt_daemon_setup_general_properties(DltLogStorage* handle, DltConfigFile* config_file, char* sec_name)
1569 : {
1570 : DltLogstorageGeneralConfType type = DLT_LOGSTORAGE_GENERAL_CONF_MAINTAIN_LOGSTORAGE_LOGLEVEL;
1571 0 : char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = {0};
1572 :
1573 0 : if ((handle == NULL) || (config_file == NULL) || (sec_name == NULL)) {
1574 : return -1;
1575 : }
1576 :
1577 0 : for (; type < DLT_LOGSTORAGE_GENERAL_CONF_COUNT; type++) {
1578 0 : if (dlt_config_file_get_value(config_file, sec_name, general_cfg_entries[type].key, value) == 0) {
1579 0 : if (dlt_logstorage_check_general_param(handle, type, value) != 0) {
1580 0 : dlt_vlog(LOG_WARNING, "General parameter %s [%s] is invalid\n", general_cfg_entries[type].key, value);
1581 : }
1582 : } else {
1583 0 : if (general_cfg_entries[type].is_opt == 1) {
1584 0 : dlt_vlog(LOG_DEBUG, "Optional General parameter %s not given\n", general_cfg_entries[type].key);
1585 : } else {
1586 0 : dlt_vlog(LOG_ERR, "General parameter %s not given\n", general_cfg_entries[type].key);
1587 0 : return -1;
1588 : }
1589 : }
1590 : }
1591 :
1592 : return 0;
1593 : }
1594 :
1595 : /**
1596 : * dlt_logstorage_store_filters
1597 : *
1598 : * This function reads the filter keys and values
1599 : * and stores them into the hash map
1600 : *
1601 : * @param handle DLT Logstorage handle
1602 : * @param config_file_name Configuration file name
1603 : * @return 0 on success, -1 on error, 1 on warning
1604 : *
1605 : */
1606 6 : DLT_STATIC int dlt_logstorage_store_filters(DltLogStorage* handle, char* config_file_name)
1607 : {
1608 : DltConfigFile* config = NULL;
1609 : int sec = 0;
1610 6 : int num_sec = 0;
1611 : int ret = 0;
1612 : /* we have to make sure that this function returns success if atleast one
1613 : * filter configuration is valid and stored */
1614 : int valid = -1;
1615 :
1616 6 : if (config_file_name == NULL) {
1617 1 : dlt_vlog(LOG_ERR, "%s unexpected parameter received\n", __func__);
1618 1 : return -1;
1619 : }
1620 :
1621 5 : config = dlt_config_file_init(config_file_name);
1622 :
1623 5 : if (config == NULL) {
1624 0 : dlt_log(LOG_CRIT, "Failed to open filter configuration file\n");
1625 0 : return -1;
1626 : }
1627 :
1628 5 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_UNDEF;
1629 5 : dlt_config_file_get_num_sections(config, &num_sec);
1630 :
1631 21 : for (sec = 0; sec < num_sec; sec++) {
1632 : char sec_name[DLT_CONFIG_FILE_ENTRY_MAX_LEN + 1];
1633 :
1634 16 : if (dlt_config_file_get_section_name(config, sec, sec_name) == -1) {
1635 0 : dlt_log(LOG_CRIT, "Failed to read section name\n");
1636 0 : dlt_config_file_release(config);
1637 0 : return -1;
1638 : }
1639 :
1640 16 : if (strstr(sec_name, GENERAL_BASE_NAME) != NULL) {
1641 0 : if (dlt_daemon_setup_general_properties(handle, config, sec_name) == -1) {
1642 0 : dlt_log(LOG_CRIT, "General configuration is invalid\n");
1643 0 : continue;
1644 : }
1645 16 : } else if (dlt_logstorage_validate_filter_name(sec_name) == 0) {
1646 16 : ret = dlt_daemon_offline_setup_filter_properties(handle, config, sec_name);
1647 :
1648 16 : if (ret == DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR) {
1649 : break;
1650 16 : } else if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR) {
1651 : valid = 1;
1652 0 : dlt_vlog(LOG_WARNING, "%s filter configuration is invalid \n", sec_name);
1653 : /* Continue reading next filter section */
1654 0 : continue;
1655 : } else
1656 : /* Filter properties read and stored successfuly */
1657 16 : if (valid != 1)
1658 : valid = 0;
1659 : } else { /* unknown section */
1660 0 : dlt_vlog(LOG_WARNING, "Unknown section: %s", sec_name);
1661 : }
1662 : }
1663 :
1664 5 : dlt_config_file_release(config);
1665 :
1666 5 : return valid;
1667 : }
1668 :
1669 : /**
1670 : * dlt_logstorage_load_config
1671 : *
1672 : * Read dlt_logstorage.conf file and setup filters in hash table
1673 : * Hash table key consists of "APID:CTID", e.g "APP1:CTX1". If
1674 : * wildcards used for application id or context id, the hash table
1675 : * key consists of none wildcard value, e.g. apid=.*, cxid=CTX1
1676 : * results in "CTX1".
1677 : *
1678 : * Combination of two wildcards is not allowed if ECUID is not specified.
1679 : *
1680 : * @param handle DLT Logstorage handle
1681 : * @return 0 on success, -1 on error, 1 on warning
1682 : */
1683 5 : DLT_STATIC int dlt_logstorage_load_config(DltLogStorage* handle)
1684 : {
1685 5 : char config_file_name[PATH_MAX] = {0};
1686 : int ret = 0;
1687 :
1688 : /* Check if handle is NULL or already initialized or already configured */
1689 5 : if ((handle == NULL) || (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED))
1690 : return -1;
1691 :
1692 : /* Check if this device config was already setup */
1693 4 : if (handle->config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) {
1694 0 : dlt_vlog(LOG_ERR, "%s: Device already configured. Send disconnect first.\n", __func__);
1695 0 : return -1;
1696 : }
1697 :
1698 4 : if (snprintf(
1699 4 : config_file_name, PATH_MAX, "%s/%s", handle->device_mount_point, DLT_OFFLINE_LOGSTORAGE_CONFIG_FILE_NAME)
1700 : < 0) {
1701 0 : dlt_log(LOG_ERR, "Creating configuration file path string failed\n");
1702 0 : return -1;
1703 : }
1704 4 : config_file_name[PATH_MAX - 1] = 0;
1705 4 : ret = dlt_logstorage_store_filters(handle, config_file_name);
1706 :
1707 4 : if (ret == 1) {
1708 0 : handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE;
1709 0 : return 1;
1710 4 : } else if (ret != 0) {
1711 0 : dlt_log(LOG_ERR, "dlt_logstorage_load_config Error : Storing filters failed\n");
1712 0 : return -1;
1713 : }
1714 :
1715 4 : handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE;
1716 :
1717 4 : return 0;
1718 : }
1719 :
1720 : /**
1721 : * dlt_logstorage_device_connected
1722 : *
1723 : * Initializes DLT Offline Logstorage with respect to device status
1724 : *
1725 : * @param handle DLT Logstorage handle
1726 : * @param mount_point Device mount path
1727 : * @return 0 on success, -1 on error, 1 on warning
1728 : */
1729 4 : int dlt_logstorage_device_connected(DltLogStorage* handle, const char* mount_point)
1730 : {
1731 4 : if ((handle == NULL) || (mount_point == NULL)) {
1732 1 : dlt_log(LOG_ERR, "Handle error \n");
1733 1 : return -1;
1734 : }
1735 :
1736 3 : if (handle->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) {
1737 0 : dlt_log(LOG_WARNING, "Device already connected. Send disconnect, connect request\n");
1738 :
1739 0 : dlt_logstorage_device_disconnected(handle, DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT);
1740 : }
1741 :
1742 3 : strncpy(handle->device_mount_point, mount_point, DLT_MOUNT_PATH_MAX);
1743 3 : handle->device_mount_point[DLT_MOUNT_PATH_MAX] = 0;
1744 3 : handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED;
1745 3 : handle->config_status = 0;
1746 3 : handle->write_errors = 0;
1747 3 : handle->num_configs = 0;
1748 3 : handle->newest_file_list = NULL;
1749 :
1750 3 : switch (handle->config_mode) {
1751 3 : case DLT_LOGSTORAGE_CONFIG_FILE:
1752 : /* Setup logstorage with config file settings */
1753 3 : return dlt_logstorage_load_config(handle);
1754 : default:
1755 : return -1;
1756 : }
1757 : }
1758 :
1759 : /**
1760 : * dlt_logstorage_device_disconnected
1761 : *
1762 : * De-Initializes DLT Offline Logstorage with respect to device status
1763 : *
1764 : * @param handle DLT Logstorage handle
1765 : * @param reason Reason for disconnect
1766 : * @return 0 on success, -1 on error
1767 : *
1768 : */
1769 3 : int dlt_logstorage_device_disconnected(DltLogStorage* handle, int reason)
1770 : {
1771 : DltNewestFileName* tmp = NULL;
1772 3 : if (handle == NULL)
1773 : return -1;
1774 :
1775 : /* If configuration loading was done, free it */
1776 2 : if (handle->config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)
1777 1 : dlt_logstorage_free(handle, reason);
1778 :
1779 : /* Reset all device status */
1780 2 : memset(handle->device_mount_point, 0, sizeof(char) * (DLT_MOUNT_PATH_MAX + 1));
1781 2 : handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED;
1782 2 : handle->config_status = 0;
1783 2 : handle->write_errors = 0;
1784 2 : handle->num_configs = 0;
1785 :
1786 14 : while (handle->newest_file_list) {
1787 : tmp = handle->newest_file_list;
1788 12 : handle->newest_file_list = tmp->next;
1789 12 : if (tmp->file_name) {
1790 12 : free(tmp->file_name);
1791 : tmp->file_name = NULL;
1792 : }
1793 12 : if (tmp->newest_file) {
1794 8 : free(tmp->newest_file);
1795 : tmp->newest_file = NULL;
1796 : }
1797 12 : free(tmp);
1798 : tmp = NULL;
1799 : }
1800 :
1801 : return 0;
1802 : }
1803 :
1804 : /**
1805 : * dlt_logstorage_get_loglevel_by_key
1806 : *
1807 : * Obtain the log level for the provided key
1808 : * This function can be used to obtain log level when the actual
1809 : * key stored in the Hash map is availble with the caller
1810 : *
1811 : * @param handle DltLogstorage handle
1812 : * @param key key to search for in Hash MAP
1813 : * @return log level on success:, -1 on error
1814 : */
1815 17 : int dlt_logstorage_get_loglevel_by_key(DltLogStorage* handle, char* key)
1816 : {
1817 17 : DltLogStorageFilterConfig* config[DLT_CONFIG_FILE_SECTIONS_MAX] = {0};
1818 : int num_configs = 0;
1819 : int i = 0;
1820 : int log_level = 0;
1821 :
1822 : /* Check if handle is NULL,already initialized or already configured */
1823 17 : if ((handle == NULL) || (key == NULL) || (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
1824 16 : || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE))
1825 : return -1;
1826 :
1827 16 : num_configs = dlt_logstorage_list_find(key, &(handle->config_list), config);
1828 :
1829 16 : if (num_configs == 0) {
1830 0 : dlt_vlog(LOG_WARNING, "Configuration for key [%s] not found!\n", key);
1831 0 : return -1;
1832 16 : } else if (num_configs == 1) {
1833 16 : if (config[0] != NULL) {
1834 16 : log_level = config[0]->log_level;
1835 : }
1836 : } else {
1837 : /**
1838 : * Multiple configurations found, raise a warning to the user and go
1839 : * for the more verbose one.
1840 : */
1841 0 : dlt_vlog(
1842 : LOG_WARNING,
1843 : "Multiple configuration for key [%s] found,"
1844 : " return the highest log level!\n",
1845 : key);
1846 :
1847 0 : for (i = 0; i < num_configs; i++) {
1848 0 : if ((config[i] != NULL) && (config[i]->log_level > log_level)) {
1849 : log_level = config[i]->log_level;
1850 : }
1851 : }
1852 : }
1853 :
1854 : return log_level;
1855 : }
1856 :
1857 : /**
1858 : * dlt_logstorage_get_config
1859 : *
1860 : * Obtain the configuration data of all filters for provided apid and ctid
1861 : *
1862 : * @param handle DltLogStorage handle
1863 : * @param config [out] Pointer to array of filter configurations
1864 : * @param apid application id
1865 : * @param ctid context id
1866 : * @param ecuid ecu id
1867 : * @return number of configurations found
1868 : */
1869 462 : int dlt_logstorage_get_config(
1870 : DltLogStorage* handle, DltLogStorageFilterConfig** config, char* apid, char* ctid, char* ecuid)
1871 : {
1872 : DltLogStorageFilterConfig** cur_config_ptr = NULL;
1873 462 : char key[DLT_CONFIG_FILE_SECTIONS_MAX][DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN] = {{'\0'}, {'\0'}, {'\0'}};
1874 : int i = 0;
1875 : size_t apid_len = 0;
1876 : size_t ctid_len = 0;
1877 : size_t ecuid_len = 0;
1878 : int num_configs = 0;
1879 : int num = 0;
1880 :
1881 : /* Check if handle is NULL,already initialized or already configured */
1882 462 : if ((handle == NULL) || (config == NULL) || (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
1883 461 : || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) || (ecuid == NULL))
1884 : return 0;
1885 :
1886 : /* Prepare possible keys with
1887 : * Possible combinations are
1888 : * ecu::
1889 : * ecu:apid:ctid
1890 : * :apid:ctid
1891 : * ecu::ctid
1892 : * ecu:apid:
1893 : * ::ctid
1894 : * :apid: */
1895 :
1896 461 : ecuid_len = strlen(ecuid);
1897 461 : if (ecuid_len > DLT_ID_SIZE)
1898 : ecuid_len = DLT_ID_SIZE;
1899 :
1900 461 : if ((apid == NULL) && (ctid == NULL)) {
1901 : /* ecu:: */
1902 2 : snprintf(key[0], sizeof(key[0]), "%.*s::", (int)ecuid_len, ecuid);
1903 :
1904 2 : num_configs = dlt_logstorage_list_find(key[0], &(handle->config_list), config);
1905 2 : return num_configs;
1906 : }
1907 :
1908 459 : if (apid != NULL) {
1909 459 : apid_len = strlen(apid);
1910 459 : if (apid_len > DLT_ID_SIZE)
1911 : apid_len = DLT_ID_SIZE;
1912 : }
1913 459 : if (ctid != NULL) {
1914 459 : ctid_len = strlen(ctid);
1915 459 : if (ctid_len > DLT_ID_SIZE)
1916 : ctid_len = DLT_ID_SIZE;
1917 : }
1918 :
1919 : /* :apid: */
1920 459 : snprintf(key[0], sizeof(key[0]), ":%.*s:", (int)apid_len, apid ? apid : "");
1921 :
1922 : /* ::ctid */
1923 459 : snprintf(key[1], sizeof(key[1]), "::%.*s", (int)ctid_len, ctid ? ctid : "");
1924 :
1925 : /* :apid:ctid */
1926 : snprintf(key[2], sizeof(key[2]), ":%.*s:%.*s", (int)apid_len, apid ? apid : "", (int)ctid_len, ctid ? ctid : "");
1927 :
1928 : /* ecu:apid:ctid */
1929 459 : snprintf(
1930 : key[3], sizeof(key[3]), "%.*s:%.*s:%.*s", (int)ecuid_len, ecuid, (int)apid_len, apid ? apid : "", (int)ctid_len,
1931 : ctid ? ctid : "");
1932 :
1933 : /* ecu:apid: */
1934 : snprintf(key[4], sizeof(key[4]), "%.*s:%.*s:", (int)ecuid_len, ecuid, (int)apid_len, apid ? apid : "");
1935 :
1936 : /* ecu::ctid */
1937 : snprintf(key[5], sizeof(key[5]), "%.*s::%.*s", (int)ecuid_len, ecuid, (int)ctid_len, ctid ? ctid : "");
1938 :
1939 : /* ecu:: */
1940 : snprintf(key[6], sizeof(key[6]), "%.*s::", (int)ecuid_len, ecuid);
1941 :
1942 3668 : for (i = 0; i < DLT_OFFLINE_LOGSTORAGE_MAX_POSSIBLE_KEYS; i++) {
1943 3210 : cur_config_ptr = &config[num_configs];
1944 3210 : num = dlt_logstorage_list_find(key[i], &(handle->config_list), cur_config_ptr);
1945 3210 : num_configs += num;
1946 : /* If all filter configurations matched, stop and return */
1947 3210 : if (num_configs == handle->num_configs) {
1948 : break;
1949 : }
1950 : }
1951 :
1952 : return num_configs;
1953 : }
1954 :
1955 : /**
1956 : * dlt_logstorage_filter
1957 : *
1958 : * Check if log message need to be stored in a certain device based on filter
1959 : * config
1960 : * - get all DltLogStorageFilterConfig from hash table possible by given
1961 : * apid/ctid (apid:, :ctid, apid:ctid
1962 : * - for each found structure, compare message log level with configured one
1963 : *
1964 : * @param handle DltLogStorage handle
1965 : * @param config Pointer to array of filter configurations
1966 : * @param apid application id
1967 : * @param ctid context id
1968 : * @param log_level Log level of message
1969 : * @param ecuid EcuID given in the message
1970 : * @return number of found configurations
1971 : */
1972 458 : DLT_STATIC int dlt_logstorage_filter(
1973 : DltLogStorage* handle, DltLogStorageFilterConfig** config, char* apid, char* ctid, char* ecuid, int log_level)
1974 : {
1975 : int i = 0;
1976 : int num = 0;
1977 :
1978 458 : if ((handle == NULL) || (config == NULL) || (ecuid == NULL))
1979 : return -1;
1980 :
1981 : /* filter on names: find DltLogStorageFilterConfig structures */
1982 457 : num = dlt_logstorage_get_config(handle, config, apid, ctid, ecuid);
1983 :
1984 457 : if (num == 0) {
1985 7 : dlt_vlog(
1986 : LOG_DEBUG, "%s: No valid filter configuration found for apid=[%.4s] ctid=[%.4s] ecuid=[%.4s]\n", __func__,
1987 : apid, ctid, ecuid);
1988 7 : return 0;
1989 : }
1990 :
1991 918 : for (i = 0; i < num; i++) {
1992 468 : if (config[i] == NULL) {
1993 0 : dlt_vlog(LOG_DEBUG, "%s: config[%d] is NULL, continue the filter loop\n", __func__, i);
1994 0 : continue;
1995 : }
1996 :
1997 : /* filter on log level */
1998 468 : if (log_level > config[i]->log_level) {
1999 6 : dlt_vlog(
2000 : LOG_DEBUG,
2001 : "%s: Requested log level (%d) is higher than config[%d]->log_level (%d). Set the config to NULL and "
2002 : "continue the filter loop\n",
2003 : __func__, log_level, i, config[i]->log_level);
2004 6 : config[i] = NULL;
2005 6 : continue;
2006 : }
2007 :
2008 : /* filter on ECU id only if EcuID is set */
2009 462 : if (config[i]->ecuid != NULL) {
2010 462 : if (strncmp(ecuid, config[i]->ecuid, DLT_ID_SIZE) != 0) {
2011 0 : dlt_vlog(
2012 : LOG_DEBUG,
2013 : "%s: ECUID does not match (Requested=%s, config[%d]=%s). Set the config to NULL and continue the "
2014 : "filter loop\n",
2015 : __func__, ecuid, i, config[i]->ecuid);
2016 0 : config[i] = NULL;
2017 0 : continue;
2018 : }
2019 : }
2020 :
2021 462 : if (config[i]->excluded_apids != NULL && config[i]->excluded_ctids != NULL) {
2022 : /* Filter on excluded application and context */
2023 6 : if (apid != NULL && ctid != NULL && dlt_logstorage_check_excluded_ids(apid, ",", config[i]->excluded_apids)
2024 3 : && dlt_logstorage_check_excluded_ids(ctid, ",", config[i]->excluded_ctids)) {
2025 3 : dlt_vlog(
2026 : LOG_DEBUG,
2027 : "%s: %s matches with [%s] and %s matches with [%s]. Set the config to NULL and continue the filter "
2028 : "loop\n",
2029 3 : __func__, apid, config[i]->excluded_apids, ctid, config[i]->excluded_ctids);
2030 3 : config[i] = NULL;
2031 : }
2032 456 : } else if (config[i]->excluded_apids == NULL) {
2033 : /* Only filter on excluded contexts */
2034 450 : if (ctid != NULL && config[i]->excluded_ctids != NULL
2035 6 : && dlt_logstorage_check_excluded_ids(ctid, ",", config[i]->excluded_ctids)) {
2036 3 : dlt_vlog(
2037 : LOG_DEBUG, "%s: %s matches with [%s]. Set the config to NULL and continue the filter loop\n",
2038 3 : __func__, ctid, config[i]->excluded_ctids);
2039 3 : config[i] = NULL;
2040 : }
2041 6 : } else if (config[i]->excluded_ctids == NULL) {
2042 : /* Only filter on excluded applications */
2043 6 : if (apid != NULL && config[i]->excluded_apids != NULL
2044 6 : && dlt_logstorage_check_excluded_ids(apid, ",", config[i]->excluded_apids)) {
2045 3 : dlt_vlog(
2046 : LOG_DEBUG, "%s: %s matches with [%s]. Set the config to NULL and continue the filter loop\n",
2047 3 : __func__, apid, config[i]->excluded_apids);
2048 3 : config[i] = NULL;
2049 : }
2050 : }
2051 : }
2052 :
2053 : return num;
2054 : }
2055 :
2056 : /**
2057 : * dlt_logstorage_write
2058 : *
2059 : * Write a message to one or more configured log files, based on filter
2060 : * configuration.
2061 : *
2062 : * @param handle DltLogStorage handle
2063 : * @param uconfig User configurations for log file
2064 : * @param data1 Data buffer of message header
2065 : * @param size1 Size of message header buffer
2066 : * @param data2 Data buffer of extended message body
2067 : * @param size2 Size of extended message body
2068 : * @param data3 Data buffer of message body
2069 : * @param size3 Size of message body
2070 : * @param disable_nw Flag to disable network routing
2071 : * @return 0 on success or write errors < max write errors, -1 on error
2072 : */
2073 451 : int dlt_logstorage_write(
2074 : DltLogStorage* handle, DltLogStorageUserConfig* uconfig, unsigned char* data1, int size1, unsigned char* data2,
2075 : int size2, unsigned char* data3, int size3, int* disable_nw)
2076 : {
2077 451 : DltLogStorageFilterConfig* config[DLT_CONFIG_FILE_SECTIONS_MAX] = {0};
2078 :
2079 : int i = 0;
2080 : int ret = 0;
2081 : int num = 0;
2082 : int err = 0;
2083 : /* data2 contains DltStandardHeader, DltStandardHeaderExtra and
2084 : * DltExtendedHeader. We are interested in ecuid, apid, ctid and loglevel */
2085 : DltExtendedHeader* extendedHeader = NULL;
2086 : DltStandardHeaderExtra* extraHeader = NULL;
2087 : DltStandardHeader* standardHeader = NULL;
2088 : size_t standardHeaderExtraLen = sizeof(DltStandardHeaderExtra);
2089 : size_t header_len = 0;
2090 : DltNewestFileName* tmp = NULL;
2091 : int found = 0;
2092 :
2093 : int log_level = -1;
2094 :
2095 451 : if ((handle == NULL) || (uconfig == NULL) || (data1 == NULL) || (data2 == NULL) || (data3 == NULL)
2096 450 : || (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
2097 450 : || (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE))
2098 : return 0;
2099 :
2100 : /* Calculate real length of DltStandardHeaderExtra */
2101 : standardHeader = (DltStandardHeader*)data2;
2102 :
2103 450 : if (!DLT_IS_HTYP_WEID(standardHeader->htyp))
2104 : standardHeaderExtraLen -= (size_t)DLT_ID_SIZE;
2105 :
2106 450 : if (!DLT_IS_HTYP_WSID(standardHeader->htyp))
2107 3 : standardHeaderExtraLen -= (size_t)DLT_SIZE_WSID;
2108 :
2109 450 : if (!DLT_IS_HTYP_WTMS(standardHeader->htyp))
2110 2 : standardHeaderExtraLen -= (size_t)DLT_SIZE_WTMS;
2111 :
2112 : extraHeader = (DltStandardHeaderExtra*)(data2 + sizeof(DltStandardHeader));
2113 :
2114 450 : if (DLT_IS_HTYP_UEH(standardHeader->htyp)) {
2115 448 : header_len = sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + standardHeaderExtraLen;
2116 :
2117 : /* check if size2 is big enough to contain expected DLT message header */
2118 448 : if ((size_t)size2 < header_len) {
2119 0 : dlt_vlog(LOG_ERR, "%s: DLT message header is too small\n", __func__);
2120 0 : return 0;
2121 : }
2122 :
2123 448 : extendedHeader = (DltExtendedHeader*)(data2 + sizeof(DltStandardHeader) + standardHeaderExtraLen);
2124 :
2125 448 : log_level = DLT_GET_MSIN_MTIN(extendedHeader->msin);
2126 :
2127 : /* check if log message need to be stored in a certain device based on
2128 : * filter configuration */
2129 448 : num = dlt_logstorage_filter(
2130 448 : handle, config, extendedHeader->apid, extendedHeader->ctid, extraHeader->ecu, log_level);
2131 :
2132 448 : if ((num == 0) || (num == -1)) {
2133 5 : dlt_vlog(
2134 : LOG_DEBUG, "%s: No valid filter configuration found for apid=[%.4s] ctid=[%.4s] ecuid=[%.4s]!\n",
2135 : __func__, extendedHeader->apid, extendedHeader->ctid, extraHeader->ecu);
2136 5 : return 0;
2137 : }
2138 : } else {
2139 2 : header_len = sizeof(DltStandardHeader) + standardHeaderExtraLen;
2140 :
2141 : /* check if size2 is big enough to contain expected DLT message header */
2142 2 : if ((size_t)size2 < header_len) {
2143 0 : dlt_log(LOG_ERR, "DLT message header is too small (without extended header)\n");
2144 0 : return 0;
2145 : }
2146 :
2147 : log_level = DLT_LOG_VERBOSE;
2148 :
2149 : /* check if log message need to be stored in a certain device based on
2150 : * filter configuration */
2151 2 : num = dlt_logstorage_filter(handle, config, NULL, NULL, extraHeader->ecu, log_level);
2152 :
2153 2 : if ((num == 0) || (num == -1)) {
2154 2 : dlt_log(LOG_DEBUG, "No valid filter configuration found!\n");
2155 2 : return 0;
2156 : }
2157 : }
2158 :
2159 : /* store log message in every found filter */
2160 890 : for (i = 0; i < num; i++) {
2161 447 : if (config[i] == NULL) {
2162 6 : dlt_vlog(LOG_DEBUG, "%s: config[%d] is NULL. Continue the filter loop\n", __func__, i);
2163 6 : continue;
2164 : }
2165 :
2166 : /* If file name is not present, the filter is non verbose control filter
2167 : * hence skip storing */
2168 441 : if (config[i]->file_name == NULL) {
2169 0 : dlt_vlog(
2170 : LOG_DEBUG,
2171 : "%s: config[%d]->file_name is NULL, which equals to non verbose control filter. Continue the filter "
2172 : "loop\n",
2173 : __func__, i);
2174 0 : continue;
2175 : }
2176 :
2177 : /* Disable network routing */
2178 441 : if ((config[i]->disable_network_routing & DLT_LOGSTORAGE_DISABLE_NW_ON) > 0) {
2179 0 : *disable_nw = 1;
2180 0 : if (config[i]->ecuid == NULL)
2181 0 : dlt_vlog(
2182 : LOG_DEBUG, "%s: Disable routing to network for ApId-CtId-EcuId [%s]-[%s]-[]\n", __func__,
2183 : config[i]->apids, config[i]->ctids);
2184 : else
2185 0 : dlt_vlog(
2186 : LOG_DEBUG, "%s: Disable routing to network for ApId-CtId-EcuId [%s]-[%s]-[%s]\n", __func__,
2187 : config[i]->apids, config[i]->ctids, config[i]->ecuid);
2188 : }
2189 :
2190 441 : if (config[i]->skip == 1) {
2191 86 : dlt_vlog(
2192 : LOG_DEBUG, "%s: config[%d] (filename=%s) is skipped. Continue the filter loop\n", __func__, i,
2193 : config[i]->file_name);
2194 86 : continue;
2195 : }
2196 :
2197 355 : tmp = handle->newest_file_list;
2198 2365 : while (tmp) {
2199 2365 : if (strcmp(tmp->file_name, config[i]->file_name) == 0) {
2200 : found = 1;
2201 : break;
2202 : } else {
2203 2010 : tmp = tmp->next;
2204 : }
2205 : }
2206 355 : if (!found) {
2207 0 : dlt_vlog(LOG_ERR, "Cannot find out record for filename [%s]\n", config[i]->file_name);
2208 0 : return -1;
2209 : }
2210 :
2211 : /* prepare log file (create and/or open)*/
2212 355 : if (config[i]->ecuid == NULL)
2213 0 : dlt_vlog(LOG_DEBUG, "%s: ApId-CtId-EcuId [%s]-[%s]-[]\n", __func__, config[i]->apids, config[i]->ctids);
2214 : else
2215 355 : dlt_vlog(
2216 : LOG_DEBUG, "%s: ApId-CtId-EcuId [%s]-[%s]-[%s]\n", __func__, config[i]->apids, config[i]->ctids,
2217 : config[i]->ecuid);
2218 :
2219 355 : if (tmp != NULL) {
2220 355 : ret = config[i]->dlt_logstorage_prepare(
2221 355 : config[i], uconfig, handle->device_mount_point, size1 + size2 + size3, tmp);
2222 : }
2223 :
2224 355 : if (ret == 0 && config[i]->skip == 1) {
2225 1 : continue;
2226 : }
2227 :
2228 : if ((ret == 0)
2229 354 : && (config[i]->sync == DLT_LOGSTORAGE_SYNC_UNSET || config[i]->sync == DLT_LOGSTORAGE_SYNC_ON_MSG)) {
2230 : /* It is abnormal if working file is still NULL after preparation. */
2231 87 : if (!config[i]->working_file_name) {
2232 0 : dlt_vlog(LOG_ERR, "Failed to prepare working file for %s\n", config[i]->file_name);
2233 0 : return -1;
2234 : } else {
2235 : /* After preparation phase, update newest file info
2236 : * it means there is new file created, newest file info must be updated.
2237 : */
2238 87 : if (tmp->newest_file) {
2239 85 : free(tmp->newest_file);
2240 85 : tmp->newest_file = NULL;
2241 : }
2242 87 : tmp->newest_file = strdup(config[i]->working_file_name);
2243 87 : tmp->wrap_id = config[i]->wrap_id;
2244 : }
2245 : }
2246 :
2247 354 : if (ret == 0) { /* log data (write) */
2248 354 : ret = config[i]->dlt_logstorage_write(
2249 354 : config[i], uconfig, handle->device_mount_point, data1, size1, data2, size2, data3, size3);
2250 :
2251 354 : if (ret == 0) {
2252 : /* In case of behavior CACHED_BASED, the newest file info
2253 : * must be updated right after writing phase.
2254 : * That is because in writing phase, it could also perform
2255 : * sync to file which actions could impact to the log file info.
2256 : * If both working file name and newest file name are unavailable,
2257 : * it means the sync to file is not performed yet, wait for next times.
2258 : */
2259 354 : if (config[i]->sync != DLT_LOGSTORAGE_SYNC_ON_MSG && config[i]->sync != DLT_LOGSTORAGE_SYNC_UNSET) {
2260 267 : if (config[i]->working_file_name) {
2261 149 : if (tmp->newest_file) {
2262 143 : free(tmp->newest_file);
2263 143 : tmp->newest_file = NULL;
2264 : }
2265 149 : tmp->newest_file = strdup(config[i]->working_file_name);
2266 149 : tmp->wrap_id = config[i]->wrap_id;
2267 : }
2268 : }
2269 :
2270 : /* flush to be sure log is stored on device */
2271 354 : ret = config[i]->dlt_logstorage_sync(
2272 : config[i], uconfig, handle->device_mount_point, DLT_LOGSTORAGE_SYNC_ON_MSG);
2273 :
2274 354 : if (ret != 0)
2275 0 : dlt_log(LOG_ERR, "dlt_logstorage_write: Unable to sync.\n");
2276 : } else {
2277 0 : handle->write_errors += 1;
2278 :
2279 0 : if (handle->write_errors >= DLT_OFFLINE_LOGSTORAGE_MAX_ERRORS)
2280 : err = -1;
2281 :
2282 0 : dlt_log(LOG_ERR, "dlt_logstorage_write: Unable to write.\n");
2283 : }
2284 : } else {
2285 0 : handle->prepare_errors += 1;
2286 :
2287 0 : if (handle->prepare_errors >= DLT_OFFLINE_LOGSTORAGE_MAX_ERRORS) {
2288 0 : config[i]->skip = 1;
2289 0 : dlt_vlog(
2290 : LOG_WARNING, "%s: Unable to prepare. Skip filename [%s] because maxmimum trial has been reached.\n",
2291 : __func__, config[i]->file_name);
2292 : } else {
2293 0 : dlt_vlog(LOG_ERR, "%s: Unable to prepare.\n", __func__);
2294 : }
2295 : }
2296 : }
2297 :
2298 : return err;
2299 : }
2300 :
2301 : /**
2302 : * dlt_logstorage_sync_caches
2303 : *
2304 : * Write Cache data to file
2305 : *
2306 : * @param handle DltLogStorage handle
2307 : * @return 0 on success, -1 on error
2308 : */
2309 3 : int dlt_logstorage_sync_caches(DltLogStorage* handle)
2310 : {
2311 : DltLogStorageFilterList** tmp = NULL;
2312 :
2313 3 : if (handle == NULL)
2314 : return -1;
2315 :
2316 3 : tmp = &(handle->config_list);
2317 :
2318 17 : while (*(tmp) != NULL) {
2319 14 : if ((*tmp)->data != NULL) {
2320 14 : if ((*tmp)->data->dlt_logstorage_sync(
2321 14 : (*tmp)->data, &handle->uconfig, handle->device_mount_point, DLT_LOGSTORAGE_SYNC_ON_DEMAND)
2322 : != 0)
2323 0 : dlt_vlog(LOG_ERR, "%s: Sync failed. Continue with next cache.\n", __func__);
2324 : }
2325 :
2326 14 : tmp = &(*tmp)->next;
2327 : }
2328 :
2329 : return 0;
2330 : }
|