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