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 40319 : 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 460064 : while (*(list) != NULL) {
271 833781 : for (i = 0; i < (*list)->num_keys; i++)
272 : {
273 419745 : if (strncmp(((*list)->key_list
274 419745 : + (i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)),
275 : key, DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN) == 0)
276 : {
277 5709 : config[num] = (*list)->data;
278 5709 : num++;
279 5709 : break;
280 : }
281 : }
282 419745 : list = &(*list)->next;
283 : }
284 :
285 40319 : 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, "Unknown gzip compression flag\n");
1344 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_ERROR;
1345 : return 1;
1346 : }
1347 : #else
1348 0 : dlt_log(LOG_WARNING, "dlt-daemon not compiled with logstorage gzip support\n");
1349 0 : config->gzip_compression = DLT_LOGSTORAGE_GZIP_OFF;
1350 : #endif
1351 0 : return 0;
1352 : }
1353 :
1354 : /**
1355 : * dlt_logstorage_check_ecuid
1356 : *
1357 : * Evaluate if ECU idenfifier given in config file
1358 : *
1359 : * @param config DltLogStorageFilterConfig
1360 : * @param value string given in config file
1361 : * @return 0 on success, -1 on error
1362 : */
1363 34 : DLT_STATIC int dlt_logstorage_check_ecuid(DltLogStorageFilterConfig *config,
1364 : char *value)
1365 : {
1366 : int len;
1367 :
1368 34 : if ((config == NULL) || (value == NULL) || (value[0] == '\0'))
1369 : return -1;
1370 :
1371 33 : if (config->ecuid != NULL) {
1372 1 : free(config->ecuid);
1373 1 : config->ecuid = NULL;
1374 : }
1375 :
1376 33 : len = strlen(value);
1377 33 : config->ecuid = calloc((len + 1), sizeof(char));
1378 :
1379 33 : if (config->ecuid == NULL)
1380 : return -1;
1381 :
1382 33 : strncpy(config->ecuid, value, len);
1383 :
1384 33 : return 0;
1385 : }
1386 :
1387 : DLT_STATIC DltLogstorageFilterConf
1388 : filter_cfg_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = {
1389 : [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = {
1390 : .key = "LogAppName",
1391 : .func = dlt_logstorage_check_apids,
1392 : .is_opt = 1
1393 : },
1394 : [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = {
1395 : .key = "ContextName",
1396 : .func = dlt_logstorage_check_ctids,
1397 : .is_opt = 1
1398 : },
1399 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_LOGAPPNAME] = {
1400 : .key = "ExcludedLogAppName",
1401 : .func = dlt_logstorage_store_config_excluded_apids,
1402 : .is_opt = 1
1403 : },
1404 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_CONTEXTNAME] = {
1405 : .key = "ExcludedContextName",
1406 : .func = dlt_logstorage_store_config_excluded_ctids,
1407 : .is_opt = 1
1408 : },
1409 : [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = {
1410 : .key = "LogLevel",
1411 : .func = dlt_logstorage_check_loglevel,
1412 : .is_opt = 0
1413 : },
1414 : [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = {
1415 : .key = NULL,
1416 : .func = dlt_logstorage_check_reset_loglevel,
1417 : .is_opt = 0
1418 : },
1419 : [DLT_LOGSTORAGE_FILTER_CONF_FILE] = {
1420 : .key = "File",
1421 : .func = dlt_logstorage_check_filename,
1422 : .is_opt = 0
1423 : },
1424 : [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = {
1425 : .key = "FileSize",
1426 : .func = dlt_logstorage_check_filesize,
1427 : .is_opt = 0
1428 : },
1429 : [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = {
1430 : .key = "NOFiles",
1431 : .func = dlt_logstorage_check_nofiles,
1432 : .is_opt = 0
1433 : },
1434 : [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = {
1435 : .key = "SyncBehavior",
1436 : .func = dlt_logstorage_check_sync_strategy,
1437 : .is_opt = 1
1438 : },
1439 : [DLT_LOGSTORAGE_FILTER_CONF_OVERWRITEBEHAVIOR] = {
1440 : .key = "OverwriteBehavior",
1441 : .func = dlt_logstorage_check_overwrite_strategy,
1442 : .is_opt = 1
1443 : },
1444 : [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = {
1445 : .key = "EcuID",
1446 : .func = dlt_logstorage_check_ecuid,
1447 : .is_opt = 1
1448 : },
1449 : [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = {
1450 : .key = "SpecificSize",
1451 : .func = dlt_logstorage_check_specificsize,
1452 : .is_opt = 1
1453 : },
1454 : [DLT_LOGSTORAGE_FILTER_CONF_GZIP_COMPRESSION] = {
1455 : .key = "GzipCompression",
1456 : .func = dlt_logstorage_check_gzip_compression,
1457 : .is_opt = 1
1458 : },
1459 : [DLT_LOGSTORAGE_FILTER_CONF_DISABLE_NETWORK] = {
1460 : .key = "DisableNetwork",
1461 : .func = dlt_logstorage_check_disable_network,
1462 : .is_opt = 1
1463 : }
1464 : };
1465 :
1466 : /* */
1467 : DLT_STATIC DltLogstorageFilterConf
1468 : filter_nonverbose_storage_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = {
1469 : [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = {
1470 : .key = NULL,
1471 : .func = dlt_logstorage_check_apids,
1472 : .is_opt = 0
1473 : },
1474 : [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = {
1475 : .key = NULL,
1476 : .func = dlt_logstorage_check_ctids,
1477 : .is_opt = 0
1478 : },
1479 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_LOGAPPNAME] = {
1480 : .key = NULL,
1481 : .func = dlt_logstorage_store_config_excluded_apids,
1482 : .is_opt = 1
1483 : },
1484 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_CONTEXTNAME] = {
1485 : .key = NULL,
1486 : .func = dlt_logstorage_store_config_excluded_ctids,
1487 : .is_opt = 1
1488 : },
1489 : [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = {
1490 : .key = NULL,
1491 : .func = dlt_logstorage_check_loglevel,
1492 : .is_opt = 0
1493 : },
1494 : [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = {
1495 : .key = NULL,
1496 : .func = NULL,
1497 : .is_opt = 0
1498 : },
1499 : [DLT_LOGSTORAGE_FILTER_CONF_FILE] = {
1500 : .key = "File",
1501 : .func = dlt_logstorage_check_filename,
1502 : .is_opt = 0
1503 : },
1504 : [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = {
1505 : .key = "FileSize",
1506 : .func = dlt_logstorage_check_filesize,
1507 : .is_opt = 0
1508 : },
1509 : [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = {
1510 : .key = "NOFiles",
1511 : .func = dlt_logstorage_check_nofiles,
1512 : .is_opt = 0
1513 : },
1514 : [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = {
1515 : .key = NULL,
1516 : .func = dlt_logstorage_check_sync_strategy,
1517 : .is_opt = 1
1518 : },
1519 : [DLT_LOGSTORAGE_FILTER_CONF_OVERWRITEBEHAVIOR] = {
1520 : .key = NULL,
1521 : .func = dlt_logstorage_check_overwrite_strategy,
1522 : .is_opt = 1
1523 : },
1524 : [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = {
1525 : .key = "EcuID",
1526 : .func = dlt_logstorage_check_ecuid,
1527 : .is_opt = 0
1528 : },
1529 : [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = {
1530 : .key = NULL,
1531 : .func = dlt_logstorage_check_specificsize,
1532 : .is_opt = 1
1533 : },
1534 : [DLT_LOGSTORAGE_FILTER_CONF_GZIP_COMPRESSION] = {
1535 : .key = "GzipCompression",
1536 : .func = dlt_logstorage_check_gzip_compression,
1537 : .is_opt = 1
1538 : },
1539 : [DLT_LOGSTORAGE_FILTER_CONF_DISABLE_NETWORK] = {
1540 : .key = NULL,
1541 : .func = dlt_logstorage_check_disable_network,
1542 : .is_opt = 1
1543 : }
1544 : };
1545 :
1546 : DLT_STATIC DltLogstorageFilterConf
1547 : filter_nonverbose_control_entries[DLT_LOGSTORAGE_FILTER_CONF_COUNT] = {
1548 : [DLT_LOGSTORAGE_FILTER_CONF_LOGAPPNAME] = {
1549 : .key = "LogAppName",
1550 : .func = dlt_logstorage_check_apids,
1551 : .is_opt = 0
1552 : },
1553 : [DLT_LOGSTORAGE_FILTER_CONF_CONTEXTNAME] = {
1554 : .key = "ContextName",
1555 : .func = dlt_logstorage_check_ctids,
1556 : .is_opt = 0
1557 : },
1558 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_LOGAPPNAME] = {
1559 : .key = NULL,
1560 : .func = dlt_logstorage_store_config_excluded_apids,
1561 : .is_opt = 1
1562 : },
1563 : [DLT_LOGSTORAGE_FILTER_CONF_EXCLUDED_CONTEXTNAME] = {
1564 : .key = NULL,
1565 : .func = dlt_logstorage_store_config_excluded_ctids,
1566 : .is_opt = 1
1567 : },
1568 : [DLT_LOGSTORAGE_FILTER_CONF_LOGLEVEL] = {
1569 : .key = "LogLevel",
1570 : .func = dlt_logstorage_check_loglevel,
1571 : .is_opt = 0
1572 : },
1573 : [DLT_LOGSTORAGE_FILTER_CONF_RESET_LOGLEVEL] = {
1574 : .key = "ResetLogLevel",
1575 : .func = dlt_logstorage_check_reset_loglevel,
1576 : .is_opt = 1
1577 : },
1578 : [DLT_LOGSTORAGE_FILTER_CONF_FILE] = {
1579 : .key = NULL,
1580 : .func = dlt_logstorage_check_filename,
1581 : .is_opt = 0
1582 : },
1583 : [DLT_LOGSTORAGE_FILTER_CONF_FILESIZE] = {
1584 : .key = NULL,
1585 : .func = dlt_logstorage_check_filesize,
1586 : .is_opt = 0
1587 : },
1588 : [DLT_LOGSTORAGE_FILTER_CONF_NOFILES] = {
1589 : .key = NULL,
1590 : .func = dlt_logstorage_check_nofiles,
1591 : .is_opt = 0
1592 : },
1593 : [DLT_LOGSTORAGE_FILTER_CONF_SYNCBEHAVIOR] = {
1594 : .key = NULL,
1595 : .func = dlt_logstorage_check_sync_strategy,
1596 : .is_opt = 1
1597 : },
1598 : [DLT_LOGSTORAGE_FILTER_CONF_OVERWRITEBEHAVIOR] = {
1599 : .key = NULL,
1600 : .func = dlt_logstorage_check_overwrite_strategy,
1601 : .is_opt = 1
1602 : },
1603 : [DLT_LOGSTORAGE_FILTER_CONF_ECUID] = {
1604 : .key = "EcuID",
1605 : .func = dlt_logstorage_check_ecuid,
1606 : .is_opt = 0
1607 : },
1608 : [DLT_LOGSTORAGE_FILTER_CONF_SPECIFIC_SIZE] = {
1609 : .key = NULL,
1610 : .func = dlt_logstorage_check_specificsize,
1611 : .is_opt = 1
1612 : },
1613 : [DLT_LOGSTORAGE_FILTER_CONF_GZIP_COMPRESSION] = {
1614 : .key = "GzipCompression",
1615 : .func = dlt_logstorage_check_gzip_compression,
1616 : .is_opt = 1
1617 : },
1618 : [DLT_LOGSTORAGE_FILTER_CONF_DISABLE_NETWORK] = {
1619 : .key = NULL,
1620 : .func = dlt_logstorage_check_disable_network,
1621 : .is_opt = 1
1622 : }
1623 : };
1624 :
1625 : /**
1626 : * Check filter configuration parameter is valid.
1627 : *
1628 : * @param config DltLogStorageFilterConfig
1629 : * @param ctype DltLogstorageFilterConfType
1630 : * @param value specified property value from configuration file
1631 : * @return 0 on success, -1 otherwise
1632 : */
1633 26 : DLT_STATIC int dlt_logstorage_check_param(DltLogStorageFilterConfig *config,
1634 : DltLogstorageFilterConfType ctype,
1635 : char *value)
1636 : {
1637 26 : if ((config == NULL) || (value == NULL))
1638 : return -1;
1639 :
1640 25 : if (ctype < DLT_LOGSTORAGE_FILTER_CONF_COUNT)
1641 25 : return filter_cfg_entries[ctype].func(config, value);
1642 :
1643 : return -1;
1644 : }
1645 :
1646 540 : DLT_STATIC int dlt_logstorage_get_filter_section_value(DltConfigFile *config_file,
1647 : char *sec_name,
1648 : DltLogstorageFilterConf entry,
1649 : char *value)
1650 : {
1651 : int ret = 0;
1652 :
1653 540 : if ((config_file == NULL) || (sec_name == NULL))
1654 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1655 :
1656 540 : if (entry.key != NULL) {
1657 504 : ret = dlt_config_file_get_value(config_file, sec_name,
1658 : entry.key,
1659 : value);
1660 :
1661 504 : if ((ret != 0) && (entry.is_opt == 0)) {
1662 0 : dlt_vlog(LOG_WARNING,
1663 : "Invalid configuration in section: %s -> %s : %s\n",
1664 : sec_name, entry.key, value);
1665 0 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1666 : }
1667 :
1668 504 : if ((ret != 0) && (entry.is_opt == 1)) {
1669 197 : dlt_vlog(LOG_DEBUG, "Optional parameter %s not specified\n",
1670 : entry.key);
1671 197 : return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE;
1672 : }
1673 : }
1674 : else {
1675 : return DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE;
1676 : }
1677 :
1678 : return 0;
1679 : }
1680 :
1681 540 : DLT_STATIC int dlt_logstorage_get_filter_value(DltConfigFile *config_file,
1682 : char *sec_name,
1683 : int index,
1684 : char *value)
1685 : {
1686 : int ret = 0;
1687 : int config_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION);
1688 : int storage_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION);
1689 : int control_sec_len = strlen(DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION);
1690 :
1691 540 : if ((config_file == NULL) || (sec_name == NULL))
1692 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1693 :
1694 : /* Branch based on section name, no complete string compare needed */
1695 540 : if (strncmp(sec_name,
1696 : DLT_OFFLINE_LOGSTORAGE_CONFIG_SECTION,
1697 : config_sec_len) == 0) {
1698 540 : ret = dlt_logstorage_get_filter_section_value(config_file, sec_name,
1699 : filter_cfg_entries[index],
1700 : value);
1701 : }
1702 0 : else if (strncmp(sec_name,
1703 : DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_STORAGE_SECTION,
1704 : storage_sec_len) == 0) {
1705 0 : ret = dlt_logstorage_get_filter_section_value(config_file, sec_name,
1706 : filter_nonverbose_storage_entries[index],
1707 : value);
1708 : }
1709 0 : else if ((strncmp(sec_name,
1710 : DLT_OFFLINE_LOGSTORAGE_NONVERBOSE_CONTROL_SECTION,
1711 : control_sec_len) == 0)) {
1712 0 : ret = dlt_logstorage_get_filter_section_value(config_file, sec_name,
1713 : filter_nonverbose_control_entries[index],
1714 : value);
1715 : }
1716 : else {
1717 0 : dlt_log(LOG_ERR, "Error: Section name not valid \n");
1718 : ret = DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1719 : }
1720 :
1721 : return ret;
1722 : }
1723 :
1724 36 : DLT_STATIC int dlt_logstorage_setup_table(DltLogStorage *handle,
1725 : DltLogStorageFilterConfig *tmp_data)
1726 : {
1727 : int ret = 0;
1728 :
1729 : /* depending on the specified strategy set function pointers for
1730 : * prepare, write and sync */
1731 36 : dlt_logstorage_filter_set_strategy(tmp_data, tmp_data->sync);
1732 :
1733 36 : ret = dlt_logstorage_prepare_table(handle, tmp_data);
1734 :
1735 36 : if (ret != 0) {
1736 0 : dlt_vlog(LOG_ERR, "%s Error: Storing filter values failed\n", __func__);
1737 : ret = DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR;
1738 : }
1739 :
1740 36 : return ret;
1741 : }
1742 : /*Return :
1743 : * DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR - On filter properties or value is not valid
1744 : * DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR - On error while storing in hash table
1745 : */
1746 :
1747 36 : DLT_STATIC int dlt_daemon_offline_setup_filter_properties(DltLogStorage *handle,
1748 : DltConfigFile *config_file,
1749 : char *sec_name)
1750 : {
1751 : DltLogStorageFilterConfig tmp_data;
1752 36 : char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN + 1] = { '\0' };
1753 : int i = 0;
1754 : int ret = 0;
1755 :
1756 36 : if ((handle == NULL) || (config_file == NULL) || (sec_name == NULL))
1757 : return DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR;
1758 :
1759 : memset(&tmp_data, 0, sizeof(DltLogStorageFilterConfig));
1760 36 : tmp_data.log_level = DLT_LOG_VERBOSE;
1761 : tmp_data.reset_log_level = DLT_LOG_OFF;
1762 36 : tmp_data.disable_network_routing = DLT_LOGSTORAGE_DISABLE_NW_OFF;
1763 :
1764 576 : for (i = 0; i < DLT_LOGSTORAGE_FILTER_CONF_COUNT; i++) {
1765 540 : ret = dlt_logstorage_get_filter_value(config_file, sec_name, i, value);
1766 :
1767 540 : if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR)
1768 : return ret;
1769 :
1770 540 : if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_CONTINUE)
1771 233 : continue;
1772 :
1773 : /* check value and store temporary */
1774 307 : ret = dlt_logstorage_check_param(&tmp_data, i, value);
1775 :
1776 307 : if (ret != 0) {
1777 0 : if (tmp_data.apids != NULL) {
1778 0 : free(tmp_data.apids);
1779 0 : tmp_data.apids = NULL;
1780 : }
1781 :
1782 0 : if (tmp_data.ctids != NULL) {
1783 0 : free(tmp_data.ctids);
1784 0 : tmp_data.ctids = NULL;
1785 : }
1786 :
1787 0 : if (tmp_data.excluded_apids != NULL) {
1788 0 : free(tmp_data.excluded_apids);
1789 0 : tmp_data.excluded_apids = NULL;
1790 : }
1791 :
1792 0 : if (tmp_data.excluded_ctids != NULL) {
1793 0 : free(tmp_data.excluded_ctids);
1794 0 : tmp_data.excluded_ctids = NULL;
1795 : }
1796 :
1797 0 : if (tmp_data.file_name != NULL) {
1798 0 : free(tmp_data.file_name);
1799 0 : tmp_data.file_name = NULL;
1800 : }
1801 :
1802 0 : if (tmp_data.working_file_name != NULL) {
1803 0 : free(tmp_data.working_file_name);
1804 0 : tmp_data.working_file_name = NULL;
1805 : }
1806 :
1807 0 : if (tmp_data.ecuid != NULL) {
1808 0 : free(tmp_data.ecuid);
1809 : tmp_data.ecuid = NULL;
1810 : }
1811 :
1812 0 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1813 : }
1814 : }
1815 :
1816 36 : if(dlt_logstorage_count_ids(tmp_data.excluded_apids) > 1 && dlt_logstorage_count_ids(tmp_data.excluded_ctids) > 1) {
1817 0 : dlt_vlog(LOG_WARNING, "%s: Logstorage does not support both multiple excluded applications and contexts\n", __func__);
1818 0 : return DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR;
1819 : }
1820 :
1821 : /* filter configuration is valid */
1822 36 : ret = dlt_logstorage_setup_table(handle, &tmp_data);
1823 :
1824 36 : if (ret != 0) {
1825 0 : dlt_vlog(LOG_ERR, "%s Error: Storing filter values failed\n", __func__);
1826 : ret = DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR;
1827 : }
1828 : else { /* move to next free filter configuration, if no error occurred */
1829 36 : handle->num_configs += 1;
1830 : }
1831 :
1832 : /* free tmp_data */
1833 36 : dlt_logstorage_filter_config_free(&tmp_data);
1834 :
1835 36 : return ret;
1836 : }
1837 :
1838 : /**
1839 : * dlt_logstorage_check_maintain_logstorage_loglevel
1840 : *
1841 : * Evaluate to maintain the logstorage loglevel setting. This is an optional
1842 : * configuration parameter
1843 : * If the given value cannot be associated with an overwrite, the default value
1844 : * will be assigned.
1845 : *
1846 : * @param config DltLogStorage
1847 : * @param value string given in config file
1848 : * @return 0 on success, -1 on error
1849 : */
1850 0 : DLT_STATIC int dlt_logstorage_check_maintain_logstorage_loglevel(DltLogStorage *handle,
1851 : char *value)
1852 : {
1853 0 : if ((handle == NULL) || (value == NULL))
1854 : {
1855 : return -1;
1856 : }
1857 :
1858 0 : if ((strncmp(value, "OFF", 3) == 0) || (strncmp(value, "0", 1) == 0))
1859 : {
1860 0 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF;
1861 : }
1862 0 : else if ((strncmp(value, "ON", 2) == 0) || (strncmp(value, "1", 1) == 0))
1863 : {
1864 0 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_ON;
1865 : }
1866 : else
1867 : {
1868 0 : dlt_vlog(LOG_ERR,
1869 : "Wrong value for Maintain logstorage loglevel section name: %s\n", value);
1870 0 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_ON;
1871 0 : return -1;
1872 : }
1873 :
1874 : return 0;
1875 : }
1876 :
1877 : DLT_STATIC DltLogstorageGeneralConf
1878 : general_cfg_entries[DLT_LOGSTORAGE_GENERAL_CONF_COUNT] = {
1879 : [DLT_LOGSTORAGE_GENERAL_CONF_MAINTAIN_LOGSTORAGE_LOGLEVEL] = {
1880 : .key = "MaintainLogstorageLogLevel",
1881 : .func = dlt_logstorage_check_maintain_logstorage_loglevel,
1882 : .is_opt = 1
1883 : }
1884 : };
1885 :
1886 : /**
1887 : * Check if DltLogstorage General configuration parameter is valid.
1888 : *
1889 : * @param handle pointer to DltLogstorage structure
1890 : * @param ctype Logstorage general configuration type
1891 : * @param value specified property value from configuration file
1892 : * @return 0 on success, -1 otherwise
1893 : */
1894 0 : DLT_STATIC int dlt_logstorage_check_general_param(DltLogStorage *handle,
1895 : DltLogstorageGeneralConfType ctype,
1896 : char *value)
1897 : {
1898 0 : if ((handle == NULL) || (value == NULL))
1899 : {
1900 : return -1;
1901 : }
1902 :
1903 0 : if (ctype < DLT_LOGSTORAGE_GENERAL_CONF_COUNT)
1904 : {
1905 0 : return general_cfg_entries[ctype].func(handle, value);
1906 : }
1907 :
1908 : return -1;
1909 : }
1910 :
1911 0 : DLT_STATIC int dlt_daemon_setup_general_properties(DltLogStorage *handle,
1912 : DltConfigFile *config_file,
1913 : char *sec_name)
1914 : {
1915 : DltLogstorageGeneralConfType type = DLT_LOGSTORAGE_GENERAL_CONF_MAINTAIN_LOGSTORAGE_LOGLEVEL;
1916 0 : char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = {0};
1917 :
1918 0 : if ((handle == NULL) || (config_file == NULL) || (sec_name == NULL))
1919 : {
1920 : return -1;
1921 : }
1922 :
1923 0 : for ( ; type < DLT_LOGSTORAGE_GENERAL_CONF_COUNT ; type++)
1924 : {
1925 0 : if (dlt_config_file_get_value(config_file,
1926 : sec_name,
1927 0 : general_cfg_entries[type].key,
1928 : value) == 0)
1929 : {
1930 0 : if (dlt_logstorage_check_general_param(handle, type, value) != 0)
1931 : {
1932 0 : dlt_vlog(LOG_WARNING,
1933 : "General parameter %s [%s] is invalid\n",
1934 : general_cfg_entries[type].key, value);
1935 : }
1936 : }
1937 : else
1938 : {
1939 0 : if (general_cfg_entries[type].is_opt == 1)
1940 : {
1941 0 : dlt_vlog(LOG_DEBUG,
1942 : "Optional General parameter %s not given\n",
1943 : general_cfg_entries[type].key);
1944 : }
1945 : else
1946 : {
1947 0 : dlt_vlog(LOG_ERR,
1948 : "General parameter %s not given\n",
1949 : general_cfg_entries[type].key);
1950 0 : return -1;
1951 : }
1952 : }
1953 : }
1954 :
1955 : return 0;
1956 : }
1957 :
1958 : /**
1959 : * dlt_logstorage_store_filters
1960 : *
1961 : * This function reads the filter keys and values
1962 : * and stores them into the hash map
1963 : *
1964 : * @param handle DLT Logstorage handle
1965 : * @param config_file_name Configuration file name
1966 : * @return 0 on success, -1 on error, 1 on warning
1967 : *
1968 : */
1969 11 : DLT_STATIC int dlt_logstorage_store_filters(DltLogStorage *handle,
1970 : char *config_file_name)
1971 : {
1972 : DltConfigFile *config = NULL;
1973 : int sec = 0;
1974 11 : int num_sec = 0;
1975 : int ret = 0;
1976 : /* we have to make sure that this function returns success if atleast one
1977 : * filter configuration is valid and stored */
1978 : int valid = -1;
1979 :
1980 11 : if (config_file_name == NULL) {
1981 1 : dlt_vlog(LOG_ERR, "%s unexpected parameter received\n", __func__);
1982 1 : return -1;
1983 : }
1984 :
1985 10 : config = dlt_config_file_init(config_file_name);
1986 :
1987 10 : if (config == NULL) {
1988 0 : dlt_log(LOG_CRIT, "Failed to open filter configuration file\n");
1989 0 : return -1;
1990 : }
1991 :
1992 10 : handle->maintain_logstorage_loglevel = DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_UNDEF;
1993 10 : dlt_config_file_get_num_sections(config, &num_sec);
1994 :
1995 46 : for (sec = 0; sec < num_sec; sec++) {
1996 : char sec_name[DLT_CONFIG_FILE_ENTRY_MAX_LEN + 1];
1997 :
1998 36 : if (dlt_config_file_get_section_name(config, sec, sec_name) == -1) {
1999 0 : dlt_log(LOG_CRIT, "Failed to read section name\n");
2000 0 : dlt_config_file_release(config);
2001 0 : return -1;
2002 : }
2003 :
2004 36 : if (strstr(sec_name, GENERAL_BASE_NAME) != NULL) {
2005 0 : if (dlt_daemon_setup_general_properties(handle, config, sec_name) == -1)
2006 : {
2007 0 : dlt_log(LOG_CRIT, "General configuration is invalid\n");
2008 0 : continue;
2009 : }
2010 : }
2011 36 : else if (dlt_logstorage_validate_filter_name(sec_name) == 0)
2012 : {
2013 36 : ret = dlt_daemon_offline_setup_filter_properties(handle, config, sec_name);
2014 :
2015 36 : if (ret == DLT_OFFLINE_LOGSTORAGE_STORE_FILTER_ERROR) {
2016 : break;
2017 : }
2018 36 : else if (ret == DLT_OFFLINE_LOGSTORAGE_FILTER_ERROR)
2019 : {
2020 : valid = 1;
2021 0 : dlt_vlog(LOG_WARNING,
2022 : "%s filter configuration is invalid \n",
2023 : sec_name);
2024 : /* Continue reading next filter section */
2025 0 : continue;
2026 : }
2027 : else
2028 : /* Filter properties read and stored successfuly */
2029 36 : if (valid != 1)
2030 : valid = 0;
2031 : }
2032 : else { /* unknown section */
2033 0 : dlt_vlog(LOG_WARNING, "Unknown section: %s", sec_name);
2034 : }
2035 : }
2036 :
2037 10 : dlt_config_file_release(config);
2038 :
2039 10 : return valid;
2040 : }
2041 :
2042 : /**
2043 : * dlt_logstorage_load_config
2044 : *
2045 : * Read dlt_logstorage.conf file and setup filters in hash table
2046 : * Hash table key consists of "APID:CTID", e.g "APP1:CTX1". If
2047 : * wildcards used for application id or context id, the hash table
2048 : * key consists of none wildcard value, e.g. apid=.*, cxid=CTX1
2049 : * results in "CTX1".
2050 : *
2051 : * Combination of two wildcards is not allowed if ECUID is not specified.
2052 : *
2053 : * @param handle DLT Logstorage handle
2054 : * @return 0 on success, -1 on error, 1 on warning
2055 : */
2056 10 : DLT_STATIC int dlt_logstorage_load_config(DltLogStorage *handle)
2057 : {
2058 10 : char config_file_name[PATH_MAX] = {0};
2059 : int ret = 0;
2060 :
2061 : /* Check if handle is NULL or already initialized or already configured */
2062 10 : if ((handle == NULL) ||
2063 9 : (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED))
2064 : return -1;
2065 :
2066 : /* Check if this device config was already setup */
2067 9 : if (handle->config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) {
2068 0 : dlt_vlog(LOG_ERR,
2069 : "%s: Device already configured. Send disconnect first.\n",
2070 : __func__);
2071 0 : return -1;
2072 : }
2073 :
2074 9 : if (snprintf(config_file_name,
2075 : PATH_MAX,
2076 : "%s/%s",
2077 9 : handle->device_mount_point,
2078 : DLT_OFFLINE_LOGSTORAGE_CONFIG_FILE_NAME) < 0) {
2079 0 : dlt_log(LOG_ERR,
2080 : "Creating configuration file path string failed\n");
2081 0 : return -1;
2082 : }
2083 9 : config_file_name[PATH_MAX - 1] = 0;
2084 9 : ret = dlt_logstorage_store_filters(handle, config_file_name);
2085 :
2086 9 : if (ret == 1) {
2087 0 : handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE;
2088 0 : return 1;
2089 : }
2090 9 : else if (ret != 0)
2091 : {
2092 0 : dlt_log(LOG_ERR,
2093 : "dlt_logstorage_load_config Error : Storing filters failed\n");
2094 0 : return -1;
2095 : }
2096 :
2097 9 : handle->config_status = DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE;
2098 :
2099 9 : return 0;
2100 : }
2101 :
2102 : /**
2103 : * dlt_logstorage_device_connected
2104 : *
2105 : * Initializes DLT Offline Logstorage with respect to device status
2106 : *
2107 : * @param handle DLT Logstorage handle
2108 : * @param mount_point Device mount path
2109 : * @return 0 on success, -1 on error, 1 on warning
2110 : */
2111 9 : int dlt_logstorage_device_connected(DltLogStorage *handle, const char *mount_point)
2112 : {
2113 9 : if ((handle == NULL) || (mount_point == NULL)) {
2114 1 : dlt_log(LOG_ERR, "Handle error \n");
2115 1 : return -1;
2116 : }
2117 :
2118 8 : if (handle->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) {
2119 0 : dlt_log(LOG_WARNING,
2120 : "Device already connected. Send disconnect, connect request\n");
2121 :
2122 0 : dlt_logstorage_device_disconnected(
2123 : handle,
2124 : DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT);
2125 : }
2126 :
2127 8 : strncpy(handle->device_mount_point, mount_point, DLT_MOUNT_PATH_MAX);
2128 8 : handle->device_mount_point[DLT_MOUNT_PATH_MAX] = 0;
2129 8 : handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED;
2130 8 : handle->config_status = 0;
2131 8 : handle->write_errors = 0;
2132 8 : handle->num_configs = 0;
2133 8 : handle->newest_file_list = NULL;
2134 :
2135 8 : switch (handle->config_mode) {
2136 8 : case DLT_LOGSTORAGE_CONFIG_FILE:
2137 : /* Setup logstorage with config file settings */
2138 8 : return dlt_logstorage_load_config(handle);
2139 : default:
2140 : return -1;
2141 : }
2142 : }
2143 :
2144 : /**
2145 : * dlt_logstorage_device_disconnected
2146 : *
2147 : * De-Initializes DLT Offline Logstorage with respect to device status
2148 : *
2149 : * @param handle DLT Logstorage handle
2150 : * @param reason Reason for disconnect
2151 : * @return 0 on success, -1 on error
2152 : *
2153 : */
2154 8 : int dlt_logstorage_device_disconnected(DltLogStorage *handle, int reason)
2155 : {
2156 : DltNewestFileName *tmp = NULL;
2157 8 : if (handle == NULL)
2158 : return -1;
2159 :
2160 : /* If configuration loading was done, free it */
2161 7 : if (handle->config_status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)
2162 6 : dlt_logstorage_free(handle, reason);
2163 :
2164 : /* Reset all device status */
2165 7 : memset(handle->device_mount_point, 0, sizeof(char) * (DLT_MOUNT_PATH_MAX + 1));
2166 7 : handle->connection_type = DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED;
2167 7 : handle->config_status = 0;
2168 7 : handle->write_errors = 0;
2169 7 : handle->num_configs = 0;
2170 :
2171 39 : while (handle->newest_file_list) {
2172 : tmp = handle->newest_file_list;
2173 32 : handle->newest_file_list = tmp->next;
2174 32 : if (tmp->file_name) {
2175 32 : free(tmp->file_name);
2176 32 : tmp->file_name = NULL;
2177 : }
2178 32 : if (tmp->newest_file) {
2179 23 : free(tmp->newest_file);
2180 : tmp->newest_file = NULL;
2181 : }
2182 32 : free(tmp);
2183 : tmp = NULL;
2184 : }
2185 :
2186 : return 0;
2187 : }
2188 :
2189 : /**
2190 : * dlt_logstorage_get_loglevel_by_key
2191 : *
2192 : * Obtain the log level for the provided key
2193 : * This function can be used to obtain log level when the actual
2194 : * key stored in the Hash map is availble with the caller
2195 : *
2196 : * @param handle DltLogstorage handle
2197 : * @param key key to search for in Hash MAP
2198 : * @return log level on success:, -1 on error
2199 : */
2200 37 : int dlt_logstorage_get_loglevel_by_key(DltLogStorage *handle, char *key)
2201 : {
2202 37 : DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 };
2203 : int num_configs = 0;
2204 : int i = 0;
2205 : int log_level = 0;
2206 :
2207 : /* Check if handle is NULL,already initialized or already configured */
2208 37 : if ((handle == NULL) ||
2209 37 : (key == NULL) ||
2210 36 : (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ||
2211 36 : (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE))
2212 : return -1;
2213 :
2214 36 : num_configs = dlt_logstorage_list_find(key, &(handle->config_list), config);
2215 :
2216 36 : if (num_configs == 0)
2217 : {
2218 0 : dlt_vlog(LOG_WARNING, "Configuration for key [%s] not found!\n", key);
2219 0 : return -1;
2220 : }
2221 36 : else if (num_configs == 1)
2222 : {
2223 36 : if (config[0] != NULL)
2224 : {
2225 36 : log_level = config[0]->log_level;
2226 : }
2227 : }
2228 : else
2229 : {
2230 : /**
2231 : * Multiple configurations found, raise a warning to the user and go
2232 : * for the more verbose one.
2233 : */
2234 0 : dlt_vlog(LOG_WARNING, "Multiple configuration for key [%s] found,"
2235 : " return the highest log level!\n", key);
2236 :
2237 0 : for (i = 0; i < num_configs; i++)
2238 : {
2239 0 : if ((config[i] != NULL) && (config[i]->log_level > log_level))
2240 : {
2241 : log_level = config[i]->log_level;
2242 : }
2243 : }
2244 : }
2245 :
2246 : return log_level;
2247 : }
2248 :
2249 : /**
2250 : * dlt_logstorage_get_config
2251 : *
2252 : * Obtain the configuration data of all filters for provided apid and ctid
2253 : *
2254 : * @param handle DltLogStorage handle
2255 : * @param config [out] Pointer to array of filter configurations
2256 : * @param apid application id
2257 : * @param ctid context id
2258 : * @param ecuid ecu id
2259 : * @return number of configurations found
2260 : */
2261 5885 : int dlt_logstorage_get_config(DltLogStorage *handle,
2262 : DltLogStorageFilterConfig **config,
2263 : char *apid,
2264 : char *ctid,
2265 : char *ecuid)
2266 : {
2267 : DltLogStorageFilterConfig **cur_config_ptr = NULL;
2268 5885 : char key[DLT_CONFIG_FILE_SECTIONS_MAX][DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN] =
2269 : { { '\0' }, { '\0' }, { '\0' } };
2270 : int i = 0;
2271 : int apid_len = 0;
2272 : int ctid_len = 0;
2273 : int ecuid_len = 0;
2274 : int num_configs = 0;
2275 : int num = 0;
2276 :
2277 : /* Check if handle is NULL,already initialized or already configured */
2278 5885 : if ((handle == NULL) || (config == NULL) ||
2279 5884 : (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ||
2280 5884 : (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) ||
2281 : (ecuid == NULL))
2282 : return 0;
2283 :
2284 : /* Prepare possible keys with
2285 : * Possible combinations are
2286 : * ecu::
2287 : * ecu:apid:ctid
2288 : * :apid:ctid
2289 : * ecu::ctid
2290 : * ecu:apid:
2291 : * ::ctid
2292 : * :apid: */
2293 :
2294 5884 : ecuid_len = strlen(ecuid);
2295 :
2296 : if (ecuid_len > DLT_ID_SIZE)
2297 : ecuid_len = DLT_ID_SIZE;
2298 :
2299 5884 : if ((apid == NULL) && (ctid == NULL)) {
2300 : /* ecu:: */
2301 0 : strncpy(key[0], ecuid, ecuid_len);
2302 : strncat(key[0], ":", 1);
2303 : strncat(key[0], ":", 1);
2304 :
2305 0 : num_configs = dlt_logstorage_list_find(key[0], &(handle->config_list),
2306 : config);
2307 0 : return num_configs;
2308 : }
2309 :
2310 5884 : if (apid != NULL){
2311 5884 : apid_len = strlen(apid);
2312 :
2313 : if (apid_len > DLT_ID_SIZE)
2314 : apid_len = DLT_ID_SIZE;
2315 : }
2316 :
2317 5884 : if (ctid != NULL){
2318 5884 : ctid_len = strlen(ctid);
2319 :
2320 : if (ctid_len > DLT_ID_SIZE)
2321 : ctid_len = DLT_ID_SIZE;
2322 : }
2323 :
2324 : /* :apid: */
2325 : strncpy(key[0], ":", 1);
2326 5884 : if (apid != NULL)
2327 5884 : strncat(key[0], apid, apid_len);
2328 : strncat(key[0], ":", 1);
2329 :
2330 : /* ::ctid */
2331 : strncpy(key[1], ":", 1);
2332 : strncat(key[1], ":", 1);
2333 5884 : if (ctid != NULL)
2334 5884 : strncat(key[1], ctid, ctid_len);
2335 :
2336 : /* :apid:ctid */
2337 : strncpy(key[2], ":", 1);
2338 5884 : if (apid != NULL)
2339 5884 : strncat(key[2], apid, apid_len);
2340 : strncat(key[2], ":", 1);
2341 5884 : if (ctid != NULL)
2342 5884 : strncat(key[2], ctid, ctid_len);
2343 :
2344 : /* ecu:apid:ctid */
2345 5884 : strncpy(key[3], ecuid, ecuid_len);
2346 : strncat(key[3], ":", 1);
2347 5884 : if (apid != NULL)
2348 5884 : strncat(key[3], apid, apid_len);
2349 : strncat(key[3], ":", 1);
2350 5884 : if (ctid != NULL)
2351 5884 : strncat(key[3], ctid, ctid_len);
2352 :
2353 : /* ecu:apid: */
2354 : strncpy(key[4], ecuid, ecuid_len);
2355 : strncat(key[4], ":", 1);
2356 5884 : if (apid != NULL)
2357 5884 : strncat(key[4], apid, apid_len);
2358 : strncat(key[4], ":", 1);
2359 :
2360 : /* ecu::ctid */
2361 : strncpy(key[5], ecuid, ecuid_len);
2362 : strncat(key[5], ":", 1);
2363 : strncat(key[5], ":", 1);
2364 5884 : if (ctid != NULL)
2365 5884 : strncat(key[5], ctid, ctid_len);
2366 :
2367 : /* ecu:: */
2368 : strncpy(key[6], ecuid, ecuid_len);
2369 : strncat(key[6], ":", 1);
2370 : strncat(key[6], ":", 1);
2371 :
2372 : /* Search the list three times with keys as -apid: , :ctid and apid:ctid */
2373 45864 : for (i = 0; i < DLT_OFFLINE_LOGSTORAGE_MAX_POSSIBLE_KEYS; i++)
2374 : {
2375 40282 : cur_config_ptr = &config[num_configs];
2376 40282 : num = dlt_logstorage_list_find(key[i], &(handle->config_list),
2377 : cur_config_ptr);
2378 40282 : num_configs += num;
2379 : /* If all filter configurations matched, stop and return */
2380 40282 : if (num_configs == handle->num_configs)
2381 : {
2382 : break;
2383 : }
2384 : }
2385 :
2386 : return num_configs;
2387 : }
2388 :
2389 : /**
2390 : * dlt_logstorage_filter
2391 : *
2392 : * Check if log message need to be stored in a certain device based on filter
2393 : * config
2394 : * - get all DltLogStorageFilterConfig from hash table possible by given
2395 : * apid/ctid (apid:, :ctid, apid:ctid
2396 : * - for each found structure, compare message log level with configured one
2397 : *
2398 : * @param handle DltLogStorage handle
2399 : * @param config Pointer to array of filter configurations
2400 : * @param apid application id
2401 : * @param ctid context id
2402 : * @param log_level Log level of message
2403 : * @param ecuid EcuID given in the message
2404 : * @return number of found configurations
2405 : */
2406 5850 : DLT_STATIC int dlt_logstorage_filter(DltLogStorage *handle,
2407 : DltLogStorageFilterConfig **config,
2408 : char *apid,
2409 : char *ctid,
2410 : char *ecuid,
2411 : int log_level)
2412 : {
2413 : int i = 0;
2414 : int num = 0;
2415 :
2416 5850 : if ((handle == NULL) || (config == NULL) || (ecuid == NULL))
2417 : return -1;
2418 :
2419 : /* filter on names: find DltLogStorageFilterConfig structures */
2420 5849 : num = dlt_logstorage_get_config(handle, config, apid, ctid, ecuid);
2421 :
2422 5849 : if (num == 0) {
2423 231 : dlt_vlog(LOG_DEBUG,
2424 : "%s: No valid filter configuration found for apid=[%.4s] ctid=[%.4s] ecuid=[%.4s]\n",
2425 : __func__, apid, ctid, ecuid);
2426 231 : return 0;
2427 : }
2428 :
2429 11254 : for (i = 0 ; i < num ; i++)
2430 : {
2431 5636 : if (config[i] == NULL)
2432 : {
2433 0 : dlt_vlog(LOG_DEBUG,
2434 : "%s: config[%d] is NULL, continue the filter loop\n",
2435 : __func__, i);
2436 0 : continue;
2437 : }
2438 :
2439 : /* filter on log level */
2440 5636 : if (log_level > config[i]->log_level) {
2441 6 : dlt_vlog(LOG_DEBUG,
2442 : "%s: Requested log level (%d) is higher than config[%d]->log_level (%d). Set the config to NULL and continue the filter loop\n",
2443 : __func__, log_level, i, config[i]->log_level);
2444 6 : config[i] = NULL;
2445 6 : continue;
2446 : }
2447 :
2448 : /* filter on ECU id only if EcuID is set */
2449 5630 : if (config[i]->ecuid != NULL) {
2450 5630 : if (strncmp(ecuid, config[i]->ecuid, DLT_ID_SIZE) != 0)
2451 : {
2452 0 : dlt_vlog(LOG_DEBUG,
2453 : "%s: ECUID does not match (Requested=%s, config[%d]=%s). Set the config to NULL and continue the filter loop\n",
2454 : __func__, ecuid, i, config[i]->ecuid);
2455 0 : config[i] = NULL;
2456 0 : continue;
2457 : }
2458 : }
2459 :
2460 5630 : if(config[i]->excluded_apids != NULL && config[i]->excluded_ctids != NULL) {
2461 : /* Filter on excluded application and context */
2462 6 : if(apid != NULL && ctid != NULL && dlt_logstorage_check_excluded_ids(apid, ",", config[i]->excluded_apids)
2463 3 : && dlt_logstorage_check_excluded_ids(ctid, ",", config[i]->excluded_ctids)) {
2464 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",
2465 3 : __func__, apid, config[i]->excluded_apids, ctid, config[i]->excluded_ctids);
2466 3 : config[i] = NULL;
2467 : }
2468 : }
2469 5624 : else if(config[i]->excluded_apids == NULL) {
2470 : /* Only filter on excluded contexts */
2471 5618 : if(ctid != NULL && config[i]->excluded_ctids != NULL && dlt_logstorage_check_excluded_ids(ctid, ",", config[i]->excluded_ctids)) {
2472 3 : dlt_vlog(LOG_DEBUG, "%s: %s matches with [%s]. Set the config to NULL and continue the filter loop\n",
2473 3 : __func__, ctid, config[i]->excluded_ctids);
2474 3 : config[i] = NULL;
2475 : }
2476 : }
2477 6 : else if(config[i]->excluded_ctids == NULL) {
2478 : /* Only filter on excluded applications */
2479 6 : if(apid != NULL && config[i]->excluded_apids != NULL && dlt_logstorage_check_excluded_ids(apid, ",", config[i]->excluded_apids)) {
2480 3 : dlt_vlog(LOG_DEBUG, "%s: %s matches with [%s]. Set the config to NULL and continue the filter loop\n",
2481 3 : __func__, apid, config[i]->excluded_apids);
2482 3 : config[i] = NULL;
2483 : }
2484 : }
2485 : }
2486 :
2487 : return num;
2488 : }
2489 :
2490 : /**
2491 : * dlt_logstorage_write
2492 : *
2493 : * Write a message to one or more configured log files, based on filter
2494 : * configuration.
2495 : *
2496 : * @param handle DltLogStorage handle
2497 : * @param uconfig User configurations for log file
2498 : * @param data1 Data buffer of message header
2499 : * @param size1 Size of message header buffer
2500 : * @param data2 Data buffer of extended message body
2501 : * @param size2 Size of extended message body
2502 : * @param data3 Data buffer of message body
2503 : * @param size3 Size of message body
2504 : * @param disable_nw Flag to disable network routing
2505 : * @return 0 on success or write errors < max write errors, -1 on error
2506 : */
2507 5843 : int dlt_logstorage_write(DltLogStorage *handle,
2508 : DltLogStorageUserConfig *uconfig,
2509 : unsigned char *data1,
2510 : int size1,
2511 : unsigned char *data2,
2512 : int size2,
2513 : unsigned char *data3,
2514 : int size3,
2515 : int *disable_nw)
2516 : {
2517 5843 : DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 };
2518 :
2519 : int i = 0;
2520 : int ret = 0;
2521 : int num = 0;
2522 : int err = 0;
2523 : /* data2 contains DltStandardHeader, DltStandardHeaderExtra and
2524 : * DltExtendedHeader. We are interested in ecuid, apid, ctid and loglevel */
2525 : DltExtendedHeader *extendedHeader = NULL;
2526 : DltStandardHeaderExtra *extraHeader = NULL;
2527 : DltStandardHeader *standardHeader = NULL;
2528 : unsigned int standardHeaderExtraLen = sizeof(DltStandardHeaderExtra);
2529 : unsigned int header_len = 0;
2530 : DltNewestFileName *tmp = NULL;
2531 : int found = 0;
2532 :
2533 : int log_level = -1;
2534 :
2535 5843 : if ((handle == NULL) || (uconfig == NULL) ||
2536 5842 : (data1 == NULL) || (data2 == NULL) || (data3 == NULL) ||
2537 5842 : (handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ||
2538 5842 : (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE))
2539 : return 0;
2540 :
2541 : /* Calculate real length of DltStandardHeaderExtra */
2542 : standardHeader = (DltStandardHeader *)data2;
2543 :
2544 5842 : if (!DLT_IS_HTYP_WEID(standardHeader->htyp))
2545 : standardHeaderExtraLen -= DLT_ID_SIZE;
2546 :
2547 5842 : if (!DLT_IS_HTYP_WSID(standardHeader->htyp))
2548 5 : standardHeaderExtraLen -= DLT_SIZE_WSID;
2549 :
2550 5842 : if (!DLT_IS_HTYP_WTMS(standardHeader->htyp))
2551 2 : standardHeaderExtraLen -= DLT_SIZE_WTMS;
2552 :
2553 : extraHeader = (DltStandardHeaderExtra *)(data2
2554 : + sizeof(DltStandardHeader));
2555 :
2556 5842 : if (DLT_IS_HTYP_UEH(standardHeader->htyp)) {
2557 5842 : header_len = sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + standardHeaderExtraLen;
2558 :
2559 : /* check if size2 is big enough to contain expected DLT message header */
2560 5842 : if ((unsigned int)size2 < header_len) {
2561 0 : dlt_vlog(LOG_ERR, "%s: DLT message header is too small\n", __func__);
2562 0 : return 0;
2563 : }
2564 :
2565 5842 : extendedHeader = (DltExtendedHeader *)(data2
2566 5842 : + sizeof(DltStandardHeader) + standardHeaderExtraLen);
2567 :
2568 5842 : log_level = DLT_GET_MSIN_MTIN(extendedHeader->msin);
2569 :
2570 : /* check if log message need to be stored in a certain device based on
2571 : * filter configuration */
2572 5842 : num = dlt_logstorage_filter(handle, config, extendedHeader->apid,
2573 5842 : extendedHeader->ctid, extraHeader->ecu, log_level);
2574 :
2575 5842 : if ((num == 0) || (num == -1)) {
2576 231 : dlt_vlog(LOG_DEBUG,
2577 : "%s: No valid filter configuration found for apid=[%.4s] ctid=[%.4s] ecuid=[%.4s]!\n",
2578 : __func__, extendedHeader->apid, extendedHeader->ctid, extraHeader->ecu);
2579 231 : return 0;
2580 : }
2581 : }
2582 : else {
2583 0 : header_len = sizeof(DltStandardHeader) + standardHeaderExtraLen;
2584 :
2585 : /* check if size2 is big enough to contain expected DLT message header */
2586 0 : if ((unsigned int)size2 < header_len) {
2587 0 : dlt_log(LOG_ERR, "DLT message header is too small (without extended header)\n");
2588 0 : return 0;
2589 : }
2590 :
2591 : log_level = DLT_LOG_VERBOSE;
2592 :
2593 : /* check if log message need to be stored in a certain device based on
2594 : * filter configuration */
2595 0 : num = dlt_logstorage_filter(handle, config, NULL,
2596 0 : NULL, extraHeader->ecu, log_level);
2597 :
2598 0 : if ((num == 0) || (num == -1)) {
2599 0 : dlt_log(LOG_DEBUG, "No valid filter configuration found!\n");
2600 0 : return 0;
2601 : }
2602 : }
2603 :
2604 : /* store log message in every found filter */
2605 11226 : for (i = 0; i < num; i++)
2606 : {
2607 5615 : if (config[i] == NULL)
2608 : {
2609 6 : dlt_vlog(LOG_DEBUG,
2610 : "%s: config[%d] is NULL. Continue the filter loop\n",
2611 : __func__, i);
2612 6 : continue;
2613 : }
2614 :
2615 : /* If file name is not present, the filter is non verbose control filter
2616 : * hence skip storing */
2617 5609 : if (config[i]->file_name == NULL)
2618 : {
2619 0 : dlt_vlog(LOG_DEBUG,
2620 : "%s: config[%d]->file_name is NULL, which equals to non verbose control filter. Continue the filter loop\n",
2621 : __func__, i);
2622 0 : continue;
2623 : }
2624 :
2625 : /* Disable network routing */
2626 5609 : if ((config[i]->disable_network_routing & DLT_LOGSTORAGE_DISABLE_NW_ON) > 0) {
2627 201 : *disable_nw = 1;
2628 201 : if (config[i]->ecuid == NULL)
2629 0 : dlt_vlog(LOG_DEBUG, "%s: Disable routing to network for ApId-CtId-EcuId [%s]-[%s]-[]\n", __func__,
2630 : config[i]->apids, config[i]->ctids);
2631 : else
2632 201 : dlt_vlog(LOG_DEBUG, "%s: Disable routing to network for ApId-CtId-EcuId [%s]-[%s]-[%s]\n", __func__,
2633 : config[i]->apids, config[i]->ctids, config[i]->ecuid);
2634 : }
2635 :
2636 5609 : if (config[i]->skip == 1)
2637 : {
2638 2157 : dlt_vlog(LOG_DEBUG,
2639 : "%s: config[%d] (filename=%s) is skipped. Continue the filter loop\n",
2640 : __func__, i, config[i]->file_name);
2641 2157 : continue;
2642 : }
2643 :
2644 3452 : tmp = handle->newest_file_list;
2645 23250 : while (tmp) {
2646 23250 : if (strcmp(tmp->file_name, config[i]->file_name) == 0) {
2647 : found = 1;
2648 : break;
2649 : }
2650 : else {
2651 19798 : tmp = tmp->next;
2652 : }
2653 : }
2654 3452 : if (!found) {
2655 0 : dlt_vlog(LOG_ERR, "Cannot find out record for filename [%s]\n",
2656 : config[i]->file_name);
2657 0 : return -1;
2658 : }
2659 :
2660 : /* prepare log file (create and/or open)*/
2661 3452 : if (config[i]->ecuid == NULL)
2662 0 : dlt_vlog(LOG_DEBUG, "%s: ApId-CtId-EcuId [%s]-[%s]-[]\n", __func__,
2663 : config[i]->apids, config[i]->ctids);
2664 : else
2665 3452 : dlt_vlog(LOG_DEBUG, "%s: ApId-CtId-EcuId [%s]-[%s]-[%s]\n", __func__,
2666 : config[i]->apids, config[i]->ctids, config[i]->ecuid);
2667 :
2668 3452 : if (tmp != NULL) {
2669 3452 : ret = config[i]->dlt_logstorage_prepare(config[i],
2670 : uconfig,
2671 3452 : handle->device_mount_point,
2672 3452 : size1 + size2 + size3,
2673 : tmp);
2674 : }
2675 :
2676 3452 : if (ret == 0 && config[i]->skip == 1) {
2677 4 : continue;
2678 : }
2679 :
2680 3448 : if ((ret == 0) &&
2681 3428 : (config[i]->sync == DLT_LOGSTORAGE_SYNC_UNSET ||
2682 : config[i]->sync == DLT_LOGSTORAGE_SYNC_ON_MSG)) {
2683 : /* It is abnormal if working file is still NULL after preparation. */
2684 339 : if (!config[i]->working_file_name) {
2685 0 : dlt_vlog(LOG_ERR, "Failed to prepare working file for %s\n",
2686 : config[i]->file_name);
2687 0 : return -1;
2688 : }
2689 : else {
2690 : /* After preparation phase, update newest file info
2691 : * it means there is new file created, newest file info must be updated.
2692 : */
2693 339 : if (tmp->newest_file) {
2694 332 : free(tmp->newest_file);
2695 332 : tmp->newest_file = NULL;
2696 : }
2697 339 : tmp->newest_file = strdup(config[i]->working_file_name);
2698 339 : tmp->wrap_id = config[i]->wrap_id;
2699 : }
2700 : }
2701 :
2702 3448 : if (ret == 0) { /* log data (write) */
2703 3428 : ret = config[i]->dlt_logstorage_write(config[i],
2704 : uconfig,
2705 3428 : handle->device_mount_point,
2706 : data1,
2707 : size1,
2708 : data2,
2709 : size2,
2710 : data3,
2711 : size3);
2712 :
2713 3428 : if (ret == 0) {
2714 : /* In case of behavior CACHED_BASED, the newest file info
2715 : * must be updated right after writing phase.
2716 : * That is because in writing phase, it could also perform
2717 : * sync to file which actions could impact to the log file info.
2718 : * If both working file name and newest file name are unavailable,
2719 : * it means the sync to file is not performed yet, wait for next times.
2720 : */
2721 3428 : if (config[i]->sync != DLT_LOGSTORAGE_SYNC_ON_MSG &&
2722 : config[i]->sync != DLT_LOGSTORAGE_SYNC_UNSET) {
2723 3089 : if (config[i]->working_file_name) {
2724 1690 : if (tmp->newest_file) {
2725 1674 : free(tmp->newest_file);
2726 1674 : tmp->newest_file = NULL;
2727 : }
2728 1690 : tmp->newest_file = strdup(config[i]->working_file_name);
2729 1690 : tmp->wrap_id = config[i]->wrap_id;
2730 : }
2731 : }
2732 :
2733 : /* flush to be sure log is stored on device */
2734 3428 : ret = config[i]->dlt_logstorage_sync(config[i],
2735 : uconfig,
2736 : handle->device_mount_point,
2737 : DLT_LOGSTORAGE_SYNC_ON_MSG);
2738 :
2739 3428 : if (ret != 0)
2740 0 : dlt_log(LOG_ERR,
2741 : "dlt_logstorage_write: Unable to sync.\n");
2742 : }
2743 : else {
2744 0 : handle->write_errors += 1;
2745 :
2746 0 : if (handle->write_errors >=
2747 : DLT_OFFLINE_LOGSTORAGE_MAX_ERRORS)
2748 : err = -1;
2749 :
2750 0 : dlt_log(LOG_ERR,
2751 : "dlt_logstorage_write: Unable to write.\n");
2752 : }
2753 : }
2754 : else {
2755 20 : handle->prepare_errors += 1;
2756 :
2757 20 : if (handle->prepare_errors >=
2758 : DLT_OFFLINE_LOGSTORAGE_MAX_ERRORS) {
2759 4 : config[i]->skip = 1;
2760 4 : dlt_vlog(LOG_WARNING,
2761 : "%s: Unable to prepare. Skip filename [%s] because maxmimum trial has been reached.\n",
2762 : __func__, config[i]->file_name);
2763 : } else {
2764 16 : dlt_vlog(LOG_ERR,
2765 : "%s: Unable to prepare.\n", __func__);
2766 : }
2767 : }
2768 : }
2769 :
2770 : return err;
2771 : }
2772 :
2773 : /**
2774 : * dlt_logstorage_sync_caches
2775 : *
2776 : * Write Cache data to file
2777 : *
2778 : * @param handle DltLogStorage handle
2779 : * @return 0 on success, -1 on error
2780 : */
2781 4 : int dlt_logstorage_sync_caches(DltLogStorage *handle)
2782 : {
2783 : DltLogStorageFilterList **tmp = NULL;
2784 :
2785 4 : if (handle == NULL)
2786 : return -1;
2787 :
2788 4 : tmp = &(handle->config_list);
2789 :
2790 30 : while (*(tmp) != NULL) {
2791 26 : if ((*tmp)->data != NULL) {
2792 26 : if ((*tmp)->data->dlt_logstorage_sync((*tmp)->data,
2793 : &handle->uconfig,
2794 26 : handle->device_mount_point,
2795 : DLT_LOGSTORAGE_SYNC_ON_DEMAND) != 0)
2796 0 : dlt_vlog(LOG_ERR,
2797 : "%s: Sync failed. Continue with next cache.\n",
2798 : __func__);
2799 : }
2800 :
2801 26 : tmp = &(*tmp)->next;
2802 :
2803 : }
2804 :
2805 : return 0;
2806 : }
|