Line data Source code
1 : /**
2 : * Copyright (C) 2013 - 2018 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_daemon_offline_logstorage.c
18 : * For further information see http://www.covesa.org/.
19 : */
20 :
21 : #include <stdio.h>
22 : #include <stdlib.h>
23 : #include <string.h>
24 : #include <syslog.h>
25 :
26 : #include "dlt_daemon_offline_logstorage.h"
27 : #include "dlt_daemon_offline_logstorage_internal.h"
28 : #include "dlt_gateway_types.h"
29 : #include "dlt_gateway.h"
30 :
31 : /**
32 : * dlt_logstorage_split_ecuid
33 : *
34 : * Split keys with ECU ID alone
35 : *
36 : * @param key Key
37 : * @param len Key length
38 : * @param ecuid ECU ID from key stored here
39 : * @param apid Application ID as .* stored here
40 : * @param ctid Context id as .* stored here
41 : * @return 0 on success -1 on error
42 : */
43 0 : DLT_STATIC DltReturnValue dlt_logstorage_split_ecuid(char *key,
44 : int len,
45 : char *ecuid,
46 : char *apid,
47 : char *ctid)
48 : {
49 0 : if ((len > (DLT_ID_SIZE + 2)) || (len < 2))
50 : return DLT_RETURN_ERROR;
51 :
52 0 : memcpy(ecuid, key, (size_t)(len - 2));
53 : memcpy(apid, ".*", 2);
54 : memcpy(ctid, ".*", 2);
55 :
56 0 : return DLT_RETURN_OK;
57 : }
58 :
59 : unsigned int g_logstorage_cache_max;
60 : /**
61 : * dlt_logstorage_split_ctid
62 : *
63 : * Split keys with Context ID alone
64 : *
65 : * @param key Key
66 : * @param len Key length
67 : * @param apid Application ID as .* stored here
68 : * @param ctid Context id from key stored here
69 : * @return 0 on success -1 on error
70 : */
71 0 : DLT_STATIC DltReturnValue dlt_logstorage_split_ctid(char *key,
72 : int len,
73 : char *apid,
74 : char *ctid)
75 : {
76 0 : if ((len > (DLT_ID_SIZE + 2)) || (len < 1))
77 : return DLT_RETURN_ERROR;
78 :
79 0 : strncpy(ctid, (key + 2), (size_t)(len - 1));
80 : memcpy(apid, ".*", 2);
81 :
82 0 : return DLT_RETURN_OK;
83 : }
84 :
85 : /**
86 : * dlt_logstorage_split_apid
87 : *
88 : * Split keys with Application ID alone
89 : *
90 : * @param key Key
91 : * @param len Key length
92 : * @param apid Application ID from key is stored here
93 : * @param ctid Context id as .* stored here
94 : * @return 0 on success -1 on error
95 : */
96 1 : DLT_STATIC DltReturnValue dlt_logstorage_split_apid(char *key,
97 : int len,
98 : char *apid,
99 : char *ctid)
100 : {
101 1 : if ((len > (DLT_ID_SIZE + 2)) || (len < 2))
102 : return DLT_RETURN_ERROR;
103 :
104 1 : strncpy(apid, key + 1, (size_t)(len - 2));
105 : memcpy(ctid, ".*", 2);
106 :
107 1 : return DLT_RETURN_OK;
108 : }
109 :
110 : /**
111 : * dlt_logstorage_split_apid_ctid
112 : *
113 : * Split keys with Application ID and Context ID
114 : *
115 : * @param key Key
116 : * @param len Key length
117 : * @param apid Application ID from key is stored here
118 : * @param ctid CContext id from key is stored here
119 : * @return 0 on success -1 on error
120 : */
121 1 : DLT_STATIC DltReturnValue dlt_logstorage_split_apid_ctid(char *key,
122 : int len,
123 : char *apid,
124 : char *ctid)
125 : {
126 : char *tok = NULL;
127 :
128 1 : if (len > DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)
129 : return DLT_RETURN_ERROR;
130 :
131 : /* copy apid and ctid */
132 1 : tok = strtok(key, ":");
133 :
134 1 : if (tok != NULL)
135 : strncpy(apid, tok, DLT_ID_SIZE);
136 : else
137 : return DLT_RETURN_ERROR;
138 :
139 1 : tok = strtok(NULL, ":");
140 :
141 1 : if (tok != NULL)
142 : strncpy(ctid, tok, DLT_ID_SIZE);
143 : else
144 : return DLT_RETURN_ERROR;
145 :
146 1 : return DLT_RETURN_OK;
147 : }
148 :
149 : /**
150 : * dlt_logstorage_split_ecuid_apid
151 : *
152 : * Split keys with ECU ID and Application ID
153 : *
154 : * @param key Key
155 : * @param len Key length
156 : * @param ecuid ECU ID from key stored here
157 : * @param apid Application ID from key is stored here
158 : * @param ctid Context id as .* stored here
159 : * @return 0 on success -1 on error
160 : */
161 1 : DLT_STATIC DltReturnValue dlt_logstorage_split_ecuid_apid(char *key,
162 : int len,
163 : char *ecuid,
164 : char *apid,
165 : char *ctid)
166 : {
167 : char *tok = NULL;
168 :
169 1 : if (len > DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)
170 : return DLT_RETURN_ERROR;
171 :
172 : /* copy apid and ctid */
173 1 : tok = strtok(key, ":");
174 :
175 1 : if (tok != NULL)
176 : strncpy(ecuid, tok, DLT_ID_SIZE);
177 : else
178 : return DLT_RETURN_ERROR;
179 :
180 1 : tok = strtok(NULL, ":");
181 :
182 1 : if (tok != NULL)
183 : strncpy(apid, tok, DLT_ID_SIZE);
184 : else
185 : return DLT_RETURN_ERROR;
186 :
187 : memcpy(ctid, ".*", 2);
188 :
189 1 : return DLT_RETURN_OK;
190 : }
191 :
192 : /**
193 : * dlt_logstorage_split_multi
194 : *
195 : * Prepares keys with application ID alone, will use ecuid if provided
196 : * (ecuid\:apid\:\:) or (\:apid\:\:)
197 : *
198 : * @param key Prepared key stored here
199 : * @param len Key length
200 : * @param ecuid ECU ID
201 : * @param apid Application ID
202 : * @param ctid Context ID
203 : * @return None
204 : */
205 14 : DLT_STATIC DltReturnValue dlt_logstorage_split_multi(char *key,
206 : int len,
207 : char *ecuid,
208 : char *apid,
209 : char *ctid)
210 : {
211 : char *tok = NULL;
212 :
213 14 : if (len > DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)
214 : return DLT_RETURN_ERROR;
215 :
216 14 : tok = strtok(key, ":");
217 :
218 14 : if (tok == NULL)
219 : return DLT_RETURN_ERROR;
220 :
221 14 : len = (int)strlen(tok);
222 :
223 14 : if (key[len + 1] == ':') {
224 : strncpy(ecuid, tok, DLT_ID_SIZE);
225 :
226 0 : tok = strtok(NULL, ":");
227 :
228 0 : if (tok != NULL)
229 : strncpy(ctid, tok, DLT_ID_SIZE);
230 :
231 : memcpy(apid, ".*", 2);
232 : }
233 : else {
234 : strncpy(ecuid, tok, DLT_ID_SIZE);
235 14 : tok = strtok(NULL, ":");
236 :
237 14 : if (tok != NULL)
238 : strncpy(apid, tok, DLT_ID_SIZE);
239 :
240 14 : tok = strtok(NULL, ":");
241 :
242 14 : if (tok != NULL)
243 : strncpy(ctid, tok, DLT_ID_SIZE);
244 : }
245 :
246 : return DLT_RETURN_OK;
247 : }
248 :
249 : /**
250 : * dlt_logstorage_split_key
251 : *
252 : * Split a given key into apid and ctid.
253 : * If APID\: - apid = APID and ctid = .*
254 : * If \:CTID - ctid = CTID and apid = .*
255 : * Else apid = APID and ctid = CTID
256 : *
257 : * @param key Given key of filter hash map
258 : * @param apid Application id
259 : * @param ctid Context id
260 : * @param ecuid ECU id
261 : * @return 0 on success, -1 on error
262 : */
263 22 : DLT_STATIC DltReturnValue dlt_logstorage_split_key(char *key, char *apid,
264 : char *ctid, char *ecuid)
265 : {
266 : int len = 0;
267 : char *sep = NULL;
268 :
269 22 : if ((key == NULL) || (apid == NULL) || (ctid == NULL) || (ecuid == NULL))
270 : return DLT_RETURN_WRONG_PARAMETER;
271 :
272 17 : len = (int)strlen(key);
273 :
274 17 : sep = strchr (key, ':');
275 :
276 17 : if (sep == NULL)
277 : return DLT_RETURN_WRONG_PARAMETER;
278 :
279 : /* key is ecuid only ecuid::*/
280 17 : if ((key[len - 1] == ':') && (key[len - 2] == ':'))
281 0 : return dlt_logstorage_split_ecuid(key, len, ecuid, apid, ctid);
282 : /* key is context id only ::apid*/
283 17 : else if ((key[0] == ':') && (key[1] == ':'))
284 0 : return dlt_logstorage_split_ctid(key, len, apid, ctid);
285 : /* key is application id only :apid: */
286 17 : else if ((key[0] == ':') && (key[len - 1] == ':'))
287 1 : return dlt_logstorage_split_apid(key, len, apid, ctid);
288 : /* key is :apid:ctid */
289 16 : else if ((key[0] == ':') && (key[len - 1] != ':'))
290 1 : return dlt_logstorage_split_apid_ctid(key, len, apid, ctid);
291 : /* key is ecuid:apid: */
292 15 : else if ((key[0] != ':') && (key[len - 1] == ':'))
293 1 : return dlt_logstorage_split_ecuid_apid(key, len, ecuid, apid, ctid);
294 : /* key is either ecuid::ctid or ecuid:apid:ctid */
295 : else
296 14 : return dlt_logstorage_split_multi(key, len, ecuid, apid, ctid);
297 : }
298 :
299 : /**
300 : * Forward SET_LOG_LEVEL request to passive node
301 : *
302 : * @param daemon_local pointer to DltDaemonLocal structure
303 : * @param apid Application ID
304 : * @param ctid Context ID
305 : * @param ecuid ECU ID
306 : * @param loglevel requested log level
307 : * @param verbose verbosity flag
308 : */
309 0 : DLT_STATIC DltReturnValue dlt_daemon_logstorage_update_passive_node_context(
310 : DltDaemonLocal *daemon_local,
311 : char *apid,
312 : char *ctid,
313 : char *ecuid,
314 : int loglevel,
315 : int verbose)
316 : {
317 0 : DltServiceSetLogLevel req = { 0 };
318 0 : DltPassiveControlMessage ctrl = { 0 };
319 : DltGatewayConnection *con = NULL;
320 :
321 0 : PRINT_FUNCTION_VERBOSE(verbose);
322 :
323 0 : if ((daemon_local == NULL) || (apid == NULL) || (ctid == NULL) || (ecuid == NULL) ||
324 0 : (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) {
325 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__);
326 0 : return DLT_RETURN_WRONG_PARAMETER;
327 : }
328 :
329 0 : con = dlt_gateway_get_connection(&daemon_local->pGateway, ecuid, verbose);
330 :
331 0 : if (con == NULL) {
332 0 : dlt_vlog(LOG_ERR,
333 : "Failed to fond connection to passive node %s\n",
334 : ecuid);
335 0 : return DLT_RETURN_ERROR;
336 : }
337 :
338 0 : ctrl.id = DLT_SERVICE_ID_SET_LOG_LEVEL;
339 0 : ctrl.type = CONTROL_MESSAGE_ON_DEMAND;
340 :
341 0 : dlt_set_id(req.apid, apid);
342 0 : dlt_set_id(req.ctid, ctid);
343 :
344 0 : req.log_level = (uint8_t)loglevel;
345 :
346 0 : if (dlt_gateway_send_control_message(con, &ctrl, (void *)&req, verbose) != 0) {
347 0 : dlt_vlog(LOG_ERR,
348 : "Failed to forward SET_LOG_LEVEL message to passive node %s\n",
349 : ecuid);
350 :
351 0 : return DLT_RETURN_ERROR;
352 : }
353 :
354 : return DLT_RETURN_OK;
355 : }
356 :
357 : /**
358 : * Forward SET_LOG_LEVEL request to passive node
359 : *
360 : * @param daemon_local pointer to DltDaemonLocal structure
361 : * @param apid Application ID
362 : * @param ctid Context ID
363 : * @param ecuid ECU ID
364 : * @param loglevel requested log level
365 : * @param verbose verbosity flag
366 : */
367 0 : DLT_STATIC DltReturnValue dlt_daemon_logstorage_update_passive_node_context_v2(
368 : DltDaemonLocal *daemon_local,
369 : char *apid,
370 : char *ctid,
371 : char *ecuid,
372 : int loglevel,
373 : int verbose)
374 : {
375 0 : DltServiceSetLogLevelV2 req = { 0 };
376 0 : DltPassiveControlMessage ctrl = { 0 };
377 : DltGatewayConnection *con = NULL;
378 :
379 0 : PRINT_FUNCTION_VERBOSE(verbose);
380 :
381 0 : if ((daemon_local == NULL) || (apid == NULL) || (ctid == NULL) || (ecuid == NULL) ||
382 0 : (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) {
383 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__);
384 0 : return DLT_RETURN_WRONG_PARAMETER;
385 : }
386 :
387 : /* Check if need to pass ecuidlen also */
388 0 : con = dlt_gateway_get_connection_v2(&daemon_local->pGateway, ecuid, verbose);
389 :
390 0 : if (con == NULL) {
391 0 : dlt_vlog(LOG_ERR,
392 : "Failed to fond connection to passive node %s\n",
393 : ecuid);
394 0 : return DLT_RETURN_ERROR;
395 : }
396 :
397 0 : ctrl.id = DLT_SERVICE_ID_SET_LOG_LEVEL;
398 0 : ctrl.type = CONTROL_MESSAGE_ON_DEMAND;
399 :
400 : /* TODO: Check apid is null terminated, to use strlen(apid) */
401 0 : req.apidlen = (uint8_t)strlen(apid);
402 : char apid_buf[DLT_V2_ID_SIZE];
403 0 : dlt_set_id_v2(apid_buf, apid, req.apidlen);
404 0 : req.apid = apid_buf;
405 : /* TODO: Check ctid is null terminated, to use strlen(apid) */
406 0 : req.ctidlen = (uint8_t)strlen(ctid);
407 : char ctid_buf[DLT_V2_ID_SIZE];
408 0 : dlt_set_id_v2(ctid_buf, ctid, req.ctidlen);
409 0 : req.ctid = ctid_buf;
410 0 : req.log_level = (uint8_t)loglevel;
411 : /* Check if need to pass ecuidlen also */
412 0 : if (dlt_gateway_send_control_message_v2(con, &ctrl, (void *)&req, verbose) != 0) {
413 0 : dlt_vlog(LOG_ERR,
414 : "Failed to forward SET_LOG_LEVEL message to passive node %s\n",
415 : ecuid);
416 :
417 0 : return DLT_RETURN_ERROR;
418 : }
419 :
420 : return DLT_RETURN_OK;
421 : }
422 :
423 : /**
424 : * dlt_daemon_logstorage_send_log_level
425 : *
426 : * Send new log level for the provided context, if ecuid is not daemon ecuid
427 : * update log level of passive node
428 : *
429 : * @param daemon DltDaemon structure
430 : * @param daemon_local DltDaemonLocal structure
431 : * @param context DltDaemonContext structure
432 : * @param ecuid ECU id
433 : * @param loglevel log level to be set to context
434 : * @param verbose If set to true verbose information is printed out
435 : * @return 0 on success, -1 on error
436 : */
437 2 : DLT_STATIC DltReturnValue dlt_daemon_logstorage_send_log_level(DltDaemon *daemon,
438 : DltDaemonLocal *daemon_local,
439 : DltDaemonContext *context,
440 : char *ecuid,
441 : int loglevel,
442 : int verbose)
443 : {
444 : int old_log_level = -1;
445 : int ll = DLT_LOG_DEFAULT;
446 :
447 2 : if ((daemon == NULL) || (daemon_local == NULL) || (ecuid == NULL) ||
448 2 : (context == NULL) || (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) {
449 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__);
450 0 : return DLT_RETURN_WRONG_PARAMETER;
451 : }
452 :
453 2 : if (strncmp(ecuid, daemon->ecuid, DLT_ID_SIZE) == 0) {
454 2 : old_log_level = context->storage_log_level;
455 :
456 2 : context->storage_log_level = (int8_t)DLT_OFFLINE_LOGSTORAGE_MAX(loglevel,
457 : context->storage_log_level);
458 :
459 2 : if (context->storage_log_level > old_log_level) {
460 2 : if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1) {
461 0 : dlt_log(LOG_ERR, "Unable to update log level\n");
462 0 : return DLT_RETURN_ERROR;
463 : }
464 : }
465 : }
466 : else {
467 :
468 0 : old_log_level = context->log_level;
469 :
470 0 : ll = DLT_OFFLINE_LOGSTORAGE_MAX(loglevel, context->log_level);
471 :
472 0 : if (ll > old_log_level)
473 0 : return dlt_daemon_logstorage_update_passive_node_context(daemon_local,
474 0 : context->apid,
475 0 : context->ctid,
476 : ecuid,
477 : ll,
478 : verbose);
479 : }
480 :
481 : return DLT_RETURN_OK;
482 : }
483 :
484 : /**
485 : * dlt_daemon_logstorage_send_log_level_v2
486 : *
487 : * DLTv2 Send new log level for the provided context, if ecuid is not daemon ecuid
488 : * update log level of passive node
489 : *
490 : * @param daemon DltDaemon structure
491 : * @param daemon_local DltDaemonLocal structure
492 : * @param context DltDaemonContext structure
493 : * @param ecuid ECU id
494 : * @param loglevel log level to be set to context
495 : * @param verbose If set to true verbose information is printed out
496 : * @return 0 on success, -1 on error
497 : */
498 0 : DLT_STATIC DltReturnValue dlt_daemon_logstorage_send_log_level_v2(DltDaemon *daemon,
499 : DltDaemonLocal *daemon_local,
500 : DltDaemonContext *context,
501 : char *ecuid,
502 : int loglevel,
503 : int verbose)
504 : {
505 : int old_log_level = -1;
506 : int ll = DLT_LOG_DEFAULT;
507 :
508 0 : if ((daemon == NULL) || (daemon_local == NULL) || (ecuid == NULL) ||
509 0 : (context == NULL) || (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) {
510 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__);
511 0 : return DLT_RETURN_WRONG_PARAMETER;
512 : }
513 :
514 0 : if (strncmp(ecuid, daemon->ecuid2, daemon->ecuid2len) == 0) {
515 0 : old_log_level = context->storage_log_level;
516 :
517 0 : context->storage_log_level = (int8_t)DLT_OFFLINE_LOGSTORAGE_MAX(loglevel,
518 : context->storage_log_level);
519 :
520 0 : if (context->storage_log_level > old_log_level) {
521 0 : if (dlt_daemon_user_send_log_level_v2(daemon, context, verbose) == -1) {
522 0 : dlt_log(LOG_ERR, "Unable to update log level\n");
523 0 : return DLT_RETURN_ERROR;
524 : }
525 : }
526 : }
527 : else {
528 :
529 0 : old_log_level = context->log_level;
530 :
531 0 : ll = DLT_OFFLINE_LOGSTORAGE_MAX(loglevel, context->log_level);
532 :
533 0 : if (ll > old_log_level)
534 0 : return dlt_daemon_logstorage_update_passive_node_context_v2(daemon_local,
535 0 : context->apid,
536 0 : context->ctid,
537 : ecuid,
538 : ll,
539 : verbose);
540 : }
541 :
542 : return DLT_RETURN_OK;
543 : }
544 :
545 : /**
546 : * dlt_daemon_logstorage_reset_log_level
547 : *
548 : * The log levels are reset if log level provided is -1 (not sent to
549 : * application in this case). Reset and sent to application if current log level
550 : * provided is 0.
551 : *
552 : * @param daemon DltDaemon structure
553 : * @param daemon_local DltDaemonLocal structure
554 : * @param context DltDaemonContext structure
555 : * @param ecuid ECU ID
556 : * @param loglevel log level to be set to context
557 : * @param verbose If set to true verbose information is printed out
558 : * @return 0 on success, -1 on error
559 : */
560 1 : DLT_STATIC DltReturnValue dlt_daemon_logstorage_reset_log_level(DltDaemon *daemon,
561 : DltDaemonLocal *daemon_local,
562 : DltDaemonContext *context,
563 : char *ecuid,
564 : int loglevel,
565 : int verbose)
566 : {
567 1 : if ((daemon == NULL) || (daemon_local == NULL) || (ecuid == NULL) ||
568 1 : (context == NULL) || (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) {
569 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__);
570 0 : return DLT_RETURN_WRONG_PARAMETER;
571 : }
572 :
573 : /* Set storage level to -1, to clear log levels */
574 1 : context->storage_log_level = DLT_LOG_DEFAULT;
575 :
576 1 : if (loglevel == DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL) {
577 1 : if (strncmp(ecuid, daemon->ecuid, DLT_ID_SIZE) == 0) {
578 1 : if (dlt_daemon_user_send_log_level(daemon,
579 : context,
580 : verbose) == DLT_RETURN_ERROR) {
581 0 : dlt_log(LOG_ERR, "Unable to update log level\n");
582 0 : return DLT_RETURN_ERROR;
583 : }
584 : }
585 : else { /* forward set log level to passive node */
586 0 : return dlt_daemon_logstorage_update_passive_node_context(daemon_local,
587 0 : context->apid,
588 0 : context->ctid,
589 : ecuid,
590 : DLT_LOG_DEFAULT,
591 : verbose);
592 : }
593 : }
594 :
595 : return DLT_RETURN_OK;
596 : }
597 :
598 : /**
599 : * dlt_daemon_logstorage_force_reset_level
600 : *
601 : * Force resetting of log level since have no data provided by passive node.
602 : *
603 : * @param daemon DltDaemon structure
604 : * @param daemon_local DltDaemonLocal structure
605 : * @param apid Application ID
606 : * @param ctid Context ID
607 : * @param ecuid ECU ID
608 : * @param loglevel log level to be set to context
609 : * @param verbose If set to true verbose information is printed out
610 : * @return 0 on success, -1 on error
611 : */
612 0 : DLT_STATIC DltReturnValue dlt_daemon_logstorage_force_reset_level(DltDaemon *daemon,
613 : DltDaemonLocal *daemon_local,
614 : char *apid,
615 : char *ctid,
616 : char *ecuid,
617 : int loglevel,
618 : int verbose)
619 : {
620 : int ll = DLT_LOG_DEFAULT;
621 : int num = 0;
622 : int i = 0;
623 0 : DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 };
624 :
625 0 : if ((daemon == NULL) || (daemon_local == NULL) || (ecuid == NULL) ||
626 0 : (apid == NULL) || (ctid == NULL) || (loglevel > DLT_LOG_VERBOSE) || (loglevel < DLT_LOG_DEFAULT)) {
627 0 : dlt_vlog(LOG_ERR, "%s: Wrong parameter\n", __func__);
628 0 : return DLT_RETURN_WRONG_PARAMETER;
629 : }
630 :
631 0 : for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) {
632 0 : num = dlt_logstorage_get_config(&(daemon->storage_handle[i]), config, apid, ctid, ecuid);
633 :
634 0 : if (num > 0)
635 : break; /* found config */
636 : }
637 :
638 0 : if ((num == 0) || (config[0] == NULL)) {
639 0 : dlt_vlog(LOG_ERR,
640 : "%s: No information about APID: %s, CTID: %s, ECU: %s in Logstorage configuration\n",
641 : __func__, apid, ctid, ecuid);
642 0 : return DLT_RETURN_ERROR;
643 : }
644 :
645 0 : if (loglevel == DLT_DAEMON_LOGSTORAGE_RESET_SEND_LOGLEVEL)
646 0 : ll = config[0]->reset_log_level;
647 : else
648 0 : ll = config[0]->log_level;
649 :
650 0 : return dlt_daemon_logstorage_update_passive_node_context(daemon_local, apid,
651 : ctid, ecuid, ll, verbose);
652 :
653 : }
654 :
655 : /**
656 : * dlt_logstorage_update_all_contexts
657 : *
658 : * Update log level of all contexts of the application by updating the daemon
659 : * internal table. The compare flags (cmp_flag) indicates if Id has to be
660 : * compared with application id or Context id of the daemon internal table.
661 : * The log levels are reset if current log level provided is -1 (not sent to
662 : * application in this case). Reset and sent to application if current log level
663 : * provided is 0.
664 : *
665 : * @param daemon DltDaemon structure
666 : * @param daemon_local DltDaemonLocal structure
667 : * @param id application id or context id
668 : * @param curr_log_level log level to be set to context
669 : * @param cmp_flag compare flag
670 : * @param ecuid ecu id where application runs
671 : * @param verbose If set to true verbose information is printed out
672 : * @return 0 on success, -1 on error
673 : */
674 4 : DltReturnValue dlt_logstorage_update_all_contexts(DltDaemon *daemon,
675 : DltDaemonLocal *daemon_local,
676 : char *id,
677 : int curr_log_level,
678 : int cmp_flag,
679 : char *ecuid,
680 : int verbose)
681 : {
682 : DltDaemonRegisteredUsers *user_list = NULL;
683 : int i = 0;
684 4 : char tmp_id[DLT_ID_SIZE + 1] = { '\0' };
685 :
686 4 : if ((daemon == NULL) || (daemon_local == NULL) || (id == NULL) ||
687 3 : (ecuid == NULL) || (cmp_flag <= DLT_DAEMON_LOGSTORAGE_CMP_MIN) ||
688 : (cmp_flag >= DLT_DAEMON_LOGSTORAGE_CMP_MAX)) {
689 1 : dlt_vlog(LOG_ERR, "Wrong parameter in function %s\n", __func__);
690 1 : return DLT_RETURN_WRONG_PARAMETER;
691 : }
692 :
693 3 : user_list = dlt_daemon_find_users_list(daemon, ecuid, verbose);
694 :
695 3 : if (user_list == NULL)
696 : return DLT_RETURN_ERROR;
697 :
698 3 : for (i = 0; i < user_list->num_contexts; i++) {
699 0 : if (cmp_flag == DLT_DAEMON_LOGSTORAGE_CMP_APID)
700 0 : dlt_set_id(tmp_id, user_list->contexts[i].apid);
701 0 : else if (cmp_flag == DLT_DAEMON_LOGSTORAGE_CMP_CTID)
702 0 : dlt_set_id(tmp_id, user_list->contexts[i].ctid);
703 : else
704 : /* this is for the case when both apid and ctid are wildcard */
705 0 : dlt_set_id(tmp_id, ".*");
706 :
707 0 : if (strncmp(id, tmp_id, DLT_ID_SIZE) == 0) {
708 0 : if (curr_log_level > 0)
709 0 : dlt_daemon_logstorage_send_log_level(daemon,
710 : daemon_local,
711 0 : &user_list->contexts[i],
712 : ecuid,
713 : curr_log_level,
714 : verbose);
715 : else /* The request is to reset log levels */
716 0 : dlt_daemon_logstorage_reset_log_level(daemon,
717 : daemon_local,
718 0 : &user_list->contexts[i],
719 : ecuid,
720 : curr_log_level,
721 : verbose);
722 : }
723 : }
724 :
725 : return DLT_RETURN_OK;
726 : }
727 :
728 : /**
729 : * dlt_logstorage_update_all_contexts_v2
730 : *
731 : * DLTv2 Update log level of all contexts of the application by updating the daemon
732 : * internal table. The compare flags (cmp_flag) indicates if Id has to be
733 : * compared with application id or Context id of the daemon internal table.
734 : * The log levels are reset if current log level provided is -1 (not sent to
735 : * application in this case). Reset and sent to application if current log level
736 : * provided is 0.
737 : *
738 : * @param daemon DltDaemon structure
739 : * @param daemon_local DltDaemonLocal structure
740 : * @param id application id or context id
741 : * @param curr_log_level log level to be set to context
742 : * @param cmp_flag compare flag
743 : * @param ecuid ecu id where application runs
744 : * @param verbose If set to true verbose information is printed out
745 : * @return 0 on success, -1 on error
746 : */
747 0 : DltReturnValue dlt_logstorage_update_all_contexts_v2(DltDaemon *daemon,
748 : DltDaemonLocal *daemon_local,
749 : char *id,
750 : int curr_log_level,
751 : int cmp_flag,
752 : char *ecuid,
753 : int verbose)
754 : {
755 : DltDaemonRegisteredUsers *user_list = NULL;
756 : int i = 0;
757 : uint8_t tmp_id_size = 0;
758 : char tmp_id[DLT_V2_ID_SIZE];
759 :
760 0 : if ((daemon == NULL) || (daemon_local == NULL) || (id == NULL) ||
761 0 : (ecuid == NULL) || (cmp_flag <= DLT_DAEMON_LOGSTORAGE_CMP_MIN) ||
762 : (cmp_flag >= DLT_DAEMON_LOGSTORAGE_CMP_MAX)) {
763 0 : dlt_vlog(LOG_ERR, "Wrong parameter in function %s\n", __func__);
764 0 : return DLT_RETURN_WRONG_PARAMETER;
765 : }
766 :
767 : /* Check ecuid length is captured using strlen in runtime */
768 0 : user_list = dlt_daemon_find_users_list_v2(daemon, (uint8_t)strlen(ecuid), ecuid, verbose);
769 :
770 0 : if (user_list == NULL)
771 : return DLT_RETURN_ERROR;
772 :
773 0 : for (i = 0; i < user_list->num_contexts; i++) {
774 0 : if (cmp_flag == DLT_DAEMON_LOGSTORAGE_CMP_APID) {
775 : /* Check tmp_id_size = apid2len + 1 is required for null termination */
776 0 : tmp_id_size = (uint8_t)(user_list->contexts[i].apid2len + 1);
777 0 : dlt_set_id_v2(tmp_id, user_list->contexts[i].apid2, user_list->contexts[i].apid2len);
778 : }
779 0 : else if (cmp_flag == DLT_DAEMON_LOGSTORAGE_CMP_CTID) {
780 : /* Check tmp_id_size = ctid2len + 1 is required for null termination */
781 0 : tmp_id_size = (uint8_t)(user_list->contexts[i].ctid2len + 1);
782 0 : dlt_set_id_v2(tmp_id, user_list->contexts[i].ctid2, user_list->contexts[i].ctid2len);
783 : }
784 : else {
785 : /* this is for the case when both apid and ctid are wildcard */
786 0 : dlt_set_id(tmp_id, ".*");
787 0 : tmp_id_size = (uint8_t)strlen(tmp_id); // 3 (2 chars + null termination)
788 : }
789 :
790 0 : if (strncmp(id, tmp_id, tmp_id_size) == 0) {
791 0 : if (curr_log_level > 0)
792 0 : dlt_daemon_logstorage_send_log_level(daemon,
793 : daemon_local,
794 0 : &user_list->contexts[i],
795 : ecuid,
796 : curr_log_level,
797 : verbose);
798 : else /* The request is to reset log levels */
799 0 : dlt_daemon_logstorage_reset_log_level(daemon,
800 : daemon_local,
801 0 : &user_list->contexts[i],
802 : ecuid,
803 : curr_log_level,
804 : verbose);
805 : }
806 : }
807 :
808 : return DLT_RETURN_OK;
809 : }
810 :
811 : /**
812 : * dlt_logstorage_update_context
813 : *
814 : * Update log level of a context by updating the daemon internal table
815 : * The log levels are reset if current log level provided is -1 (not sent to
816 : * application in this case)
817 : * Reset and sent to application if current log level provided is 0
818 : *
819 : * @param daemon DltDaemon structure
820 : * @param daemon_local DltDaemonLocal structure
821 : * @param apid application id
822 : * @param ctid context id
823 : * @param ecuid ecu id
824 : * @param curr_log_level log level to be set to context
825 : * @param verbose If set to true verbose information is printed out
826 : * @return 0 on success, -1 on error
827 : */
828 18 : DltReturnValue dlt_logstorage_update_context(DltDaemon *daemon,
829 : DltDaemonLocal *daemon_local,
830 : char *apid,
831 : char *ctid,
832 : char *ecuid,
833 : int curr_log_level,
834 : int verbose)
835 : {
836 : DltDaemonContext *context = NULL;
837 :
838 18 : if ((daemon == NULL) || (daemon_local == NULL) || (apid == NULL)
839 17 : || (ctid == NULL) || (ecuid == NULL)) {
840 1 : dlt_vlog(LOG_ERR, "Wrong parameter in function %s\n", __func__);
841 1 : return DLT_RETURN_WRONG_PARAMETER;
842 : }
843 :
844 17 : context = dlt_daemon_context_find(daemon, apid, ctid, ecuid, verbose);
845 :
846 17 : if (context != NULL) {
847 3 : if (curr_log_level > 0)
848 2 : return dlt_daemon_logstorage_send_log_level(daemon,
849 : daemon_local,
850 : context,
851 : ecuid,
852 : curr_log_level,
853 : verbose);
854 : else /* The request is to reset log levels */
855 1 : return dlt_daemon_logstorage_reset_log_level(daemon,
856 : daemon_local,
857 : context,
858 : ecuid,
859 : curr_log_level,
860 : verbose);
861 : }
862 : else {
863 14 : if (strncmp(ecuid, daemon->ecuid, DLT_ID_SIZE) != 0) {
864 : /* we intentionally have no data provided by passive node. */
865 : /* We blindly send the log level or reset log level */
866 0 : return dlt_daemon_logstorage_force_reset_level(daemon,
867 : daemon_local,
868 : apid,
869 : ctid,
870 : ecuid,
871 : curr_log_level,
872 : verbose);
873 : }
874 : else {
875 14 : dlt_vlog(LOG_WARNING,
876 : "%s: No information about APID: %s, CTID: %s, ECU: %s\n",
877 : __func__,
878 : apid,
879 : ctid,
880 : ecuid);
881 14 : return DLT_RETURN_ERROR;
882 :
883 : }
884 : }
885 :
886 : return DLT_RETURN_OK;
887 : }
888 :
889 : /**
890 : * dlt_logstorage_update_context_loglevel
891 : *
892 : * Update all contexts or particular context depending provided key
893 : *
894 : * @param daemon Pointer to DLT Daemon structure
895 : * @param daemon_local Pointer to DLT Daemon Local structure
896 : * @param key Filter key stored in Hash Map
897 : * @param curr_log_level log level to be set to context
898 : * @param verbose If set to true verbose information is printed out
899 : * @return 0 on success, -1 on error
900 : */
901 17 : DltReturnValue dlt_logstorage_update_context_loglevel(DltDaemon *daemon,
902 : DltDaemonLocal *daemon_local,
903 : char *key,
904 : int curr_log_level,
905 : int verbose)
906 : {
907 : int cmp_flag = 0;
908 17 : char apid[DLT_ID_SIZE + 1] = { '\0' };
909 17 : char ctid[DLT_ID_SIZE + 1] = { '\0' };
910 17 : char ecuid[DLT_ID_SIZE + 1] = { '\0' };
911 :
912 17 : PRINT_FUNCTION_VERBOSE(verbose);
913 :
914 17 : if ((daemon == NULL) || (daemon_local == NULL) || (key == NULL))
915 : return DLT_RETURN_WRONG_PARAMETER;
916 :
917 16 : if (dlt_logstorage_split_key(key, apid, ctid, ecuid) != 0) {
918 0 : dlt_log(LOG_ERR,
919 : "Error while updating application log levels (split key)\n");
920 0 : return DLT_RETURN_ERROR;
921 : }
922 :
923 16 : if (ecuid[0] == '\0') /* ECU id was not specified in filter configuration */
924 2 : dlt_set_id(ecuid, daemon->ecuid);
925 :
926 : /* check wildcard for both apid and ctid first of all */
927 16 : if (strcmp(ctid, ".*") == 0 && strcmp(apid, ".*") == 0) {
928 : cmp_flag = DLT_DAEMON_LOGSTORAGE_CMP_ECID;
929 :
930 0 : if (dlt_logstorage_update_all_contexts(daemon,
931 : daemon_local,
932 : apid,
933 : curr_log_level,
934 : cmp_flag,
935 : ecuid,
936 : verbose) != 0)
937 : return DLT_RETURN_ERROR;
938 : }
939 16 : else if (strcmp(ctid, ".*") == 0) {
940 : cmp_flag = DLT_DAEMON_LOGSTORAGE_CMP_APID;
941 :
942 1 : if (dlt_logstorage_update_all_contexts(daemon,
943 : daemon_local,
944 : apid,
945 : curr_log_level,
946 : cmp_flag,
947 : ecuid,
948 : verbose) != 0)
949 : return DLT_RETURN_ERROR;
950 : }
951 : /* wildcard for application id, find all contexts with context id */
952 15 : else if (strcmp(apid, ".*") == 0)
953 : {
954 : cmp_flag = DLT_DAEMON_LOGSTORAGE_CMP_CTID;
955 :
956 0 : if (dlt_logstorage_update_all_contexts(daemon,
957 : daemon_local,
958 : ctid,
959 : curr_log_level,
960 : cmp_flag,
961 : ecuid,
962 : verbose) != 0)
963 : return DLT_RETURN_ERROR;
964 : }
965 : /* In case of given application id, context id pair, call available context
966 : * find function */
967 15 : else if (dlt_logstorage_update_context(daemon,
968 : daemon_local,
969 : apid,
970 : ctid,
971 : ecuid,
972 : curr_log_level,
973 : verbose) != 0)
974 : {
975 : return DLT_RETURN_ERROR;
976 : }
977 :
978 : return DLT_RETURN_OK;
979 : }
980 :
981 : /**
982 : * dlt_logstorage_update_context_loglevel_v2
983 : *
984 : * DLTv2 Update all contexts or particular context depending provided key
985 : *
986 : * @param daemon Pointer to DLT Daemon structure
987 : * @param daemon_local Pointer to DLT Daemon Local structure
988 : * @param key Filter key stored in Hash Map
989 : * @param curr_log_level log level to be set to context
990 : * @param verbose If set to true verbose information is printed out
991 : * @return 0 on success, -1 on error
992 : */
993 0 : DltReturnValue dlt_logstorage_update_context_loglevel_v2(DltDaemon *daemon,
994 : DltDaemonLocal *daemon_local,
995 : char *key,
996 : int curr_log_level,
997 : int verbose)
998 : {
999 : int cmp_flag = 0;
1000 0 : char apid[DLT_ID_SIZE + 1] = { '\0' };
1001 0 : char ctid[DLT_ID_SIZE + 1] = { '\0' };
1002 0 : char ecuid[DLT_ID_SIZE + 1] = { '\0' };
1003 :
1004 0 : PRINT_FUNCTION_VERBOSE(verbose);
1005 :
1006 0 : if ((daemon == NULL) || (daemon_local == NULL) || (key == NULL))
1007 : return DLT_RETURN_WRONG_PARAMETER;
1008 :
1009 : //TBD: REVIEW Add dlt_logstorage_split_key_v2 function to handle variable length IDs
1010 0 : if (dlt_logstorage_split_key(key, apid, ctid, ecuid) != 0) {
1011 0 : dlt_log(LOG_ERR,
1012 : "Error while updating application log levels (split key)\n");
1013 0 : return DLT_RETURN_ERROR;
1014 : }
1015 :
1016 0 : if (ecuid[0] == '\0') /* ECU id was not specified in filter configuration */
1017 0 : dlt_set_id_v2(ecuid, daemon->ecuid2, daemon->ecuid2len);
1018 :
1019 : /* check wildcard for both apid and ctid first of all */
1020 0 : if (strcmp(ctid, ".*") == 0 && strcmp(apid, ".*") == 0) {
1021 : cmp_flag = DLT_DAEMON_LOGSTORAGE_CMP_ECID;
1022 :
1023 0 : if (dlt_logstorage_update_all_contexts(daemon,
1024 : daemon_local,
1025 : apid,
1026 : curr_log_level,
1027 : cmp_flag,
1028 : ecuid,
1029 : verbose) != 0)
1030 : return DLT_RETURN_ERROR;
1031 : }
1032 0 : else if (strcmp(ctid, ".*") == 0) {
1033 : cmp_flag = DLT_DAEMON_LOGSTORAGE_CMP_APID;
1034 :
1035 0 : if (dlt_logstorage_update_all_contexts(daemon,
1036 : daemon_local,
1037 : apid,
1038 : curr_log_level,
1039 : cmp_flag,
1040 : ecuid,
1041 : verbose) != 0)
1042 : return DLT_RETURN_ERROR;
1043 : }
1044 : /* wildcard for application id, find all contexts with context id */
1045 0 : else if (strcmp(apid, ".*") == 0)
1046 : {
1047 : cmp_flag = DLT_DAEMON_LOGSTORAGE_CMP_CTID;
1048 :
1049 0 : if (dlt_logstorage_update_all_contexts(daemon,
1050 : daemon_local,
1051 : ctid,
1052 : curr_log_level,
1053 : cmp_flag,
1054 : ecuid,
1055 : verbose) != 0)
1056 : return DLT_RETURN_ERROR;
1057 : }
1058 : /* In case of given application id, context id pair, call available context
1059 : * find function */
1060 0 : else if (dlt_logstorage_update_context(daemon,
1061 : daemon_local,
1062 : apid,
1063 : ctid,
1064 : ecuid,
1065 : curr_log_level,
1066 : verbose) != 0)
1067 : {
1068 : return DLT_RETURN_ERROR;
1069 : }
1070 :
1071 : return DLT_RETURN_OK;
1072 : }
1073 :
1074 : /**
1075 : * dlt_daemon_logstorage_reset_application_loglevel
1076 : *
1077 : * Reset storage log level of all running applications
1078 : * 2 steps for resetting
1079 : * 1. Setup storage_loglevel of all contexts configured for the requested device
1080 : * to -1
1081 : * 2. Re-run update log level for all other configured devices
1082 : *
1083 : * @param daemon Pointer to DLT Daemon structure
1084 : * @param daemon_local Pointer to DLT Daemon local structure
1085 : * @param dev_num Number of attached DLT Logstorage device
1086 : * @param max_device Maximum storage devices setup by the daemon
1087 : * @param verbose If set to true verbose information is printed out
1088 : */
1089 2 : void dlt_daemon_logstorage_reset_application_loglevel(DltDaemon *daemon,
1090 : DltDaemonLocal *daemon_local,
1091 : int dev_num,
1092 : int max_device,
1093 : int verbose)
1094 : {
1095 : DltLogStorage *handle = NULL;
1096 : DltLogStorageFilterList **tmp = NULL;
1097 : int i = 0;
1098 2 : char key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { '\0' };
1099 : unsigned int status;
1100 : int log_level = 0;
1101 :
1102 2 : PRINT_FUNCTION_VERBOSE(verbose);
1103 :
1104 2 : if ((daemon == NULL) || (daemon_local == NULL) ||
1105 1 : (daemon->storage_handle == NULL) || (dev_num < 0)) {
1106 2 : dlt_vlog(LOG_ERR,
1107 : "Invalid function parameters used for %s\n",
1108 : __func__);
1109 2 : return;
1110 : }
1111 :
1112 0 : handle = &(daemon->storage_handle[dev_num]);
1113 :
1114 0 : if ((handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ||
1115 0 : (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE))
1116 : return;
1117 :
1118 : /* for all filters (keys) check if application context are already running
1119 : * and log level need to be reset*/
1120 0 : tmp = &(handle->config_list);
1121 0 : while (*(tmp) != NULL)
1122 : {
1123 0 : for (i = 0; i < (*tmp)->num_keys; i++)
1124 : {
1125 : memset(key, 0, sizeof(key));
1126 :
1127 0 : strncpy(key, ((*tmp)->key_list
1128 0 : + (i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)),
1129 : DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN);
1130 :
1131 : /* dlt-daemon wants to reset loglevel if
1132 : * a logstorage device is disconnected.
1133 : */
1134 : log_level = DLT_DAEMON_LOGSTORAGE_RESET_LOGLEVEL;
1135 :
1136 0 : dlt_logstorage_update_context_loglevel(
1137 : daemon,
1138 : daemon_local,
1139 : key,
1140 : log_level,
1141 : verbose);
1142 : }
1143 0 : tmp = &(*tmp)->next;
1144 : }
1145 :
1146 : /* Re-run update log level for all other configured devices */
1147 0 : for (i = 0; i < max_device; i++) {
1148 0 : status = daemon->storage_handle[i].config_status;
1149 :
1150 0 : if (i == dev_num)
1151 0 : continue;
1152 :
1153 0 : if (status == DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE)
1154 0 : dlt_daemon_logstorage_update_application_loglevel(daemon,
1155 : daemon_local,
1156 : i,
1157 : verbose);
1158 : }
1159 :
1160 : return;
1161 : }
1162 :
1163 : /**
1164 : * dlt_daemon_logstorage_update_application_loglevel
1165 : *
1166 : * Update log level of all running applications with new filter configuration
1167 : * available due to newly attached DltLogstorage device. The log level is only
1168 : * updated when the current application log level is less than the log level
1169 : * obtained from the storage configuration file
1170 : *
1171 : * @param daemon Pointer to DLT Daemon structure
1172 : * @param daemon_local Pointer to DLT Daemon local structure
1173 : * @param dev_num Number of attached DLT Logstorage device
1174 : * @param verbose If set to true verbose information is printed out
1175 : */
1176 5 : void dlt_daemon_logstorage_update_application_loglevel(DltDaemon *daemon,
1177 : DltDaemonLocal *daemon_local,
1178 : int dev_num,
1179 : int verbose)
1180 : {
1181 : DltLogStorage *handle = NULL;
1182 : DltLogStorageFilterList **tmp = NULL;
1183 5 : char key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { '\0' };
1184 : int i = 0;
1185 : int log_level = 0;
1186 :
1187 5 : PRINT_FUNCTION_VERBOSE(verbose);
1188 :
1189 5 : if ((daemon == NULL) || (daemon_local == NULL) || (dev_num < 0))
1190 : {
1191 1 : dlt_vlog(LOG_ERR,
1192 : "Invalid function parameters used for %s\n",
1193 : __func__);
1194 1 : return;
1195 : }
1196 :
1197 4 : handle = &(daemon->storage_handle[dev_num]);
1198 :
1199 4 : if ((handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ||
1200 4 : (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE))
1201 : return;
1202 :
1203 : /* for all filters (keys) check if application or context already running
1204 : * and log level need to be updated*/
1205 4 : tmp = &(handle->config_list);
1206 19 : while (*(tmp) != NULL)
1207 : {
1208 30 : for (i = 0; i < (*tmp)->num_keys; i++)
1209 : {
1210 : memset(key, 0, sizeof(key));
1211 :
1212 15 : strncpy(key, ((*tmp)->key_list
1213 15 : + (i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)),
1214 : DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN);
1215 :
1216 : /* Obtain storage configuration data */
1217 15 : log_level = dlt_logstorage_get_loglevel_by_key(handle, key);
1218 15 : if (log_level < 0)
1219 : {
1220 0 : dlt_log(LOG_ERR, "Failed to get log level by key \n");
1221 0 : return;
1222 : }
1223 :
1224 : /* Update context log level with storage configuration log level */
1225 15 : dlt_logstorage_update_context_loglevel(daemon,
1226 : daemon_local,
1227 : key,
1228 : log_level,
1229 : verbose);
1230 : }
1231 15 : tmp = &(*tmp)->next;
1232 : }
1233 :
1234 : return;
1235 : }
1236 :
1237 : /**
1238 : * dlt_daemon_logstorage_update_application_loglevel_v2
1239 : *
1240 : * DLTv2 Update log level of all running applications with new filter configuration
1241 : * available due to newly attached DltLogstorage device. The log level is only
1242 : * updated when the current application log level is less than the log level
1243 : * obtained from the storage configuration file
1244 : *
1245 : * @param daemon Pointer to DLT Daemon structure
1246 : * @param daemon_local Pointer to DLT Daemon local structure
1247 : * @param dev_num Number of attached DLT Logstorage device
1248 : * @param verbose If set to true verbose information is printed out
1249 : */
1250 0 : void dlt_daemon_logstorage_update_application_loglevel_v2(DltDaemon *daemon,
1251 : DltDaemonLocal *daemon_local,
1252 : int dev_num,
1253 : int verbose)
1254 : {
1255 : DltLogStorage *handle = NULL;
1256 : DltLogStorageFilterList **tmp = NULL;
1257 0 : char key[DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN + 1] = { '\0' };
1258 : int i = 0;
1259 : int log_level = 0;
1260 :
1261 0 : PRINT_FUNCTION_VERBOSE(verbose);
1262 :
1263 0 : if ((daemon == NULL) || (daemon_local == NULL) || (dev_num < 0))
1264 : {
1265 0 : dlt_vlog(LOG_ERR,
1266 : "Invalid function parameters used for %s\n",
1267 : __func__);
1268 0 : return;
1269 : }
1270 :
1271 0 : handle = &(daemon->storage_handle[dev_num]);
1272 :
1273 0 : if ((handle->connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) ||
1274 0 : (handle->config_status != DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE))
1275 : return;
1276 :
1277 : /* for all filters (keys) check if application or context already running
1278 : * and log level need to be updated*/
1279 0 : tmp = &(handle->config_list);
1280 0 : while (*(tmp) != NULL)
1281 : {
1282 0 : for (i = 0; i < (*tmp)->num_keys; i++)
1283 : {
1284 : memset(key, 0, sizeof(key));
1285 :
1286 0 : strncpy(key, ((*tmp)->key_list
1287 0 : + (i * DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN)),
1288 : DLT_OFFLINE_LOGSTORAGE_MAX_KEY_LEN);
1289 :
1290 : /* Obtain storage configuration data */
1291 0 : log_level = dlt_logstorage_get_loglevel_by_key(handle, key);
1292 0 : if (log_level < 0)
1293 : {
1294 0 : dlt_log(LOG_ERR, "Failed to get log level by key \n");
1295 0 : return;
1296 : }
1297 :
1298 : /* Update context log level with storage configuration log level */
1299 0 : dlt_logstorage_update_context_loglevel(daemon,
1300 : daemon_local,
1301 : key,
1302 : log_level,
1303 : verbose);
1304 : }
1305 0 : tmp = &(*tmp)->next;
1306 : }
1307 :
1308 : return;
1309 : }
1310 :
1311 : /**
1312 : * dlt_daemon_logstorage_get_loglevel
1313 : *
1314 : * Obtain log level as a union of all configured storage devices and filters for
1315 : * the provided application id and context id
1316 : *
1317 : * @param daemon Pointer to DLT Daemon structure
1318 : * @param max_device Maximum storage devices setup by the daemon
1319 : * @param apid Application ID
1320 : * @param ctid Context ID
1321 : * @return Log level on success, -1 on error
1322 : */
1323 2 : int dlt_daemon_logstorage_get_loglevel(DltDaemon *daemon,
1324 : int max_device,
1325 : char *apid,
1326 : char *ctid)
1327 : {
1328 2 : DltLogStorageFilterConfig *config[DLT_CONFIG_FILE_SECTIONS_MAX] = { 0 };
1329 : int i = 0;
1330 : int j = 0;
1331 : int8_t storage_loglevel = -1;
1332 : int8_t configured_loglevel = -1;
1333 : int num_config = 0;
1334 :
1335 2 : if ((daemon == NULL) || (max_device == 0) || (apid == NULL) || (ctid == NULL))
1336 : return DLT_RETURN_WRONG_PARAMETER;
1337 :
1338 2 : for (i = 0; i < max_device; i++)
1339 1 : if (daemon->storage_handle[i].config_status ==
1340 : DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) {
1341 1 : num_config = dlt_logstorage_get_config(&(daemon->storage_handle[i]),
1342 : config,
1343 : apid,
1344 : ctid,
1345 1 : daemon->ecuid);
1346 :
1347 1 : if (num_config == 0) {
1348 0 : dlt_log(LOG_DEBUG, "No valid filter configuration found\n");
1349 0 : continue;
1350 : }
1351 :
1352 2 : for (j = 0; j < num_config; j++)
1353 : {
1354 1 : if (config[j] == NULL)
1355 0 : continue;
1356 :
1357 : /* If logstorage configuration do not contain file name,
1358 : * then it is non verbose control filter, so return level as in this filter */
1359 1 : if (config[j]->file_name == NULL) {
1360 0 : storage_loglevel = (int8_t)config[j]->log_level;
1361 0 : break;
1362 : }
1363 :
1364 1 : configured_loglevel = (int8_t)config[j]->log_level;
1365 1 : storage_loglevel = (int8_t)DLT_OFFLINE_LOGSTORAGE_MAX(
1366 : configured_loglevel,
1367 : storage_loglevel);
1368 : }
1369 : }
1370 :
1371 1 : return storage_loglevel;
1372 : }
1373 :
1374 : /**
1375 : * dlt_daemon_logstorage_write
1376 : *
1377 : * Write log message to all attached storage device. If the called
1378 : * dlt_logstorage_write function is not able to write to the device, DltDaemon
1379 : * will disconnect this device.
1380 : *
1381 : * @param daemon Pointer to Dlt Daemon structure
1382 : * @param user_config DltDaemon configuration
1383 : * @param data1 message header buffer
1384 : * @param size1 message header buffer size
1385 : * @param data2 message extended header buffer
1386 : * @param size2 message extended header size
1387 : * @param data3 message data buffer
1388 : * @param size3 message data size
1389 : * @return 0 on success, -1 on error, 1 on disable network routing
1390 : */
1391 396 : int dlt_daemon_logstorage_write(DltDaemon *daemon,
1392 : DltDaemonFlags *user_config,
1393 : unsigned char *data1,
1394 : int size1,
1395 : unsigned char *data2,
1396 : int size2,
1397 : unsigned char *data3,
1398 : int size3)
1399 : {
1400 : static bool disable_nw_warning_sent = false;
1401 : int i = 0;
1402 : int ret = 0;
1403 : DltLogStorageUserConfig file_config;
1404 :
1405 396 : if ((daemon == NULL) || (user_config == NULL) ||
1406 395 : (user_config->offlineLogstorageMaxDevices <= 0) || (data1 == NULL) ||
1407 395 : (data2 == NULL) || (data3 == NULL)) {
1408 1 : dlt_vlog(LOG_DEBUG,
1409 : "%s: message type is not LOG. Skip storing.\n",
1410 : __func__);
1411 1 : return -1;
1412 : /* Log Level changed callback */
1413 : }
1414 :
1415 : /* Copy user configuration */
1416 395 : file_config.logfile_timestamp = user_config->offlineLogstorageTimestamp;
1417 395 : file_config.logfile_delimiter = user_config->offlineLogstorageDelimiter;
1418 395 : file_config.logfile_maxcounter = user_config->offlineLogstorageMaxCounter;
1419 395 : file_config.logfile_optional_counter = user_config->offlineLogstorageOptionalCounter;
1420 395 : file_config.logfile_counteridxlen =
1421 395 : user_config->offlineLogstorageMaxCounterIdx;
1422 :
1423 790 : for (i = 0; i < user_config->offlineLogstorageMaxDevices; i++) {
1424 395 : if (daemon->storage_handle[i].config_status ==
1425 : DLT_OFFLINE_LOGSTORAGE_CONFIG_DONE) {
1426 395 : int disable_nw = 0;
1427 395 : if ((ret = dlt_logstorage_write(&(daemon->storage_handle[i]),
1428 : &file_config,
1429 : data1,
1430 : size1,
1431 : data2,
1432 : size2,
1433 : data3,
1434 : size3,
1435 : &disable_nw)) < 0) {
1436 0 : dlt_log(LOG_ERR,
1437 : "dlt_daemon_logstorage_write: failed. "
1438 : "Disable storage device\n");
1439 : /* DLT_OFFLINE_LOGSTORAGE_MAX_ERRORS happened,
1440 : * therefore remove logstorage device */
1441 0 : dlt_logstorage_device_disconnected(
1442 0 : &(daemon->storage_handle[i]),
1443 : DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT);
1444 : }
1445 395 : if (disable_nw == 1) {
1446 0 : if (i == 0) {
1447 : ret = 1;
1448 : }
1449 0 : else if (disable_nw_warning_sent == false) {
1450 0 : disable_nw_warning_sent = true;
1451 0 : dlt_vlog(LOG_WARNING,
1452 : "%s: DisableNetwork is not supported for more "
1453 : "than one device yet\n",
1454 : __func__);
1455 : }
1456 : }
1457 : }
1458 : }
1459 :
1460 : return ret;
1461 : }
1462 :
1463 : /**
1464 : * dlt_daemon_logstorage_setup_internal_storage
1465 : *
1466 : * Setup user defined path as offline log storage device
1467 : *
1468 : * @param daemon Pointer to Dlt Daemon structure
1469 : * @param daemon_local Pointer to Dlt Daemon local structure
1470 : * @param path User configured internal storage path
1471 : * @param verbose If set to true verbose information is printed out
1472 : * @return 0 on sucess, -1 otherwise
1473 : */
1474 3 : int dlt_daemon_logstorage_setup_internal_storage(DltDaemon *daemon,
1475 : DltDaemonLocal *daemon_local,
1476 : char *path,
1477 : int verbose)
1478 : {
1479 : int ret = 0;
1480 :
1481 3 : PRINT_FUNCTION_VERBOSE(verbose);
1482 :
1483 3 : if ((path == NULL) || (daemon == NULL))
1484 : return DLT_RETURN_WRONG_PARAMETER;
1485 :
1486 : /* connect internal storage device */
1487 : /* Device index always used as 0 as it is setup on DLT daemon startup */
1488 2 : ret = dlt_logstorage_device_connected(&(daemon->storage_handle[0]), path);
1489 :
1490 2 : if (ret != 0) {
1491 0 : dlt_vlog(LOG_ERR, "%s: Device connect failed\n", __func__);
1492 0 : return DLT_RETURN_ERROR;
1493 : }
1494 :
1495 : /* check if log level of running application need an update */
1496 2 : dlt_daemon_logstorage_update_application_loglevel(daemon,
1497 : daemon_local,
1498 : 0,
1499 : verbose);
1500 :
1501 2 : if (daemon->storage_handle[0].maintain_logstorage_loglevel !=
1502 : DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_UNDEF) {
1503 0 : daemon->maintain_logstorage_loglevel =
1504 : daemon->storage_handle[0].maintain_logstorage_loglevel;
1505 :
1506 0 : dlt_vlog(LOG_DEBUG, "[%s] Startup with maintain loglevel: [%d]\n",
1507 : __func__,
1508 : daemon->storage_handle[0].maintain_logstorage_loglevel);
1509 : }
1510 :
1511 : return ret;
1512 : }
1513 :
1514 2 : void dlt_daemon_logstorage_set_logstorage_cache_size(unsigned int size)
1515 : {
1516 : /* store given [KB] size in [Bytes] */
1517 2 : g_logstorage_cache_max = size * 1024;
1518 2 : }
1519 :
1520 3 : int dlt_daemon_logstorage_cleanup(DltDaemon *daemon,
1521 : DltDaemonLocal *daemon_local,
1522 : int verbose)
1523 : {
1524 : int i = 0;
1525 :
1526 3 : PRINT_FUNCTION_VERBOSE(verbose);
1527 :
1528 3 : if ((daemon == NULL) || (daemon_local == NULL) || (daemon->storage_handle == NULL))
1529 : return DLT_RETURN_WRONG_PARAMETER;
1530 :
1531 4 : for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++)
1532 : /* call disconnect on all currently connected devices */
1533 2 : if (daemon->storage_handle[i].connection_type ==
1534 : DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
1535 : {
1536 1 : (&daemon->storage_handle[i])->uconfig.logfile_counteridxlen =
1537 1 : daemon_local->flags.offlineLogstorageMaxCounterIdx;
1538 1 : (&daemon->storage_handle[i])->uconfig.logfile_delimiter =
1539 1 : daemon_local->flags.offlineLogstorageDelimiter;
1540 1 : (&daemon->storage_handle[i])->uconfig.logfile_maxcounter =
1541 1 : daemon_local->flags.offlineLogstorageMaxCounter;
1542 1 : (&daemon->storage_handle[i])->uconfig.logfile_timestamp =
1543 1 : daemon_local->flags.offlineLogstorageTimestamp;
1544 1 : (&daemon->storage_handle[i])->uconfig.logfile_optional_counter =
1545 1 : daemon_local->flags.offlineLogstorageOptionalCounter;
1546 :
1547 1 : dlt_logstorage_device_disconnected(
1548 : &daemon->storage_handle[i],
1549 : DLT_LOGSTORAGE_SYNC_ON_DAEMON_EXIT);
1550 : }
1551 :
1552 : return 0;
1553 : }
1554 :
1555 3 : int dlt_daemon_logstorage_sync_cache(DltDaemon *daemon,
1556 : DltDaemonLocal *daemon_local,
1557 : char *mnt_point,
1558 : int verbose)
1559 : {
1560 : int i = 0;
1561 : DltLogStorage *handle = NULL;
1562 :
1563 3 : PRINT_FUNCTION_VERBOSE(verbose);
1564 :
1565 3 : if ((daemon == NULL) || (daemon_local == NULL) || (mnt_point == NULL))
1566 : return DLT_RETURN_WRONG_PARAMETER;
1567 :
1568 2 : if (strlen(mnt_point) > 0) { /* mount point is given */
1569 2 : handle = dlt_daemon_logstorage_get_device(daemon,
1570 : daemon_local,
1571 : mnt_point,
1572 : verbose);
1573 :
1574 2 : if (handle == NULL) {
1575 : return DLT_RETURN_ERROR;
1576 : }
1577 : else {
1578 2 : handle->uconfig.logfile_counteridxlen =
1579 2 : daemon_local->flags.offlineLogstorageMaxCounterIdx;
1580 2 : handle->uconfig.logfile_delimiter =
1581 2 : daemon_local->flags.offlineLogstorageDelimiter;
1582 2 : handle->uconfig.logfile_maxcounter =
1583 2 : daemon_local->flags.offlineLogstorageMaxCounter;
1584 2 : handle->uconfig.logfile_timestamp =
1585 2 : daemon_local->flags.offlineLogstorageTimestamp;
1586 2 : handle->uconfig.logfile_optional_counter =
1587 2 : daemon_local->flags.offlineLogstorageOptionalCounter;
1588 :
1589 2 : if (dlt_logstorage_sync_caches(handle) != 0)
1590 : return DLT_RETURN_ERROR;
1591 : }
1592 : }
1593 : else { /* sync caches for all connected logstorage devices */
1594 :
1595 0 : for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++)
1596 0 : if (daemon->storage_handle[i].connection_type ==
1597 : DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) {
1598 0 : daemon->storage_handle[i].uconfig.logfile_counteridxlen =
1599 0 : daemon_local->flags.offlineLogstorageMaxCounterIdx;
1600 0 : daemon->storage_handle[i].uconfig.logfile_delimiter =
1601 0 : daemon_local->flags.offlineLogstorageDelimiter;
1602 0 : daemon->storage_handle[i].uconfig.logfile_maxcounter =
1603 0 : daemon_local->flags.offlineLogstorageMaxCounter;
1604 0 : daemon->storage_handle[i].uconfig.logfile_timestamp =
1605 0 : daemon_local->flags.offlineLogstorageTimestamp;
1606 0 : daemon->storage_handle[i].uconfig.logfile_optional_counter =
1607 0 : daemon_local->flags.offlineLogstorageOptionalCounter;
1608 :
1609 0 : if (dlt_logstorage_sync_caches(&daemon->storage_handle[i]) != 0)
1610 : return DLT_RETURN_ERROR;
1611 : }
1612 : }
1613 :
1614 : return 0;
1615 : }
1616 :
1617 4 : DltLogStorage *dlt_daemon_logstorage_get_device(DltDaemon *daemon,
1618 : DltDaemonLocal *daemon_local,
1619 : char *mnt_point,
1620 : int verbose)
1621 : {
1622 : int i = 0;
1623 : int len = 0;
1624 : int len1 = 0;
1625 : int len2 = 0;
1626 :
1627 4 : PRINT_FUNCTION_VERBOSE(verbose);
1628 :
1629 4 : if ((daemon == NULL) || (daemon_local == NULL) || (mnt_point == NULL))
1630 : return NULL;
1631 :
1632 3 : len1 = (int)strlen(mnt_point);
1633 :
1634 3 : for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) {
1635 3 : len2 = (int)strlen(daemon->storage_handle[i].device_mount_point);
1636 :
1637 : /* Check if the requested device path is already used as log storage
1638 : * device. Check for strlen first, to avoid comparison errors when
1639 : * final '/' is given or not */
1640 3 : len = len1 > len2 ? len2 : len1;
1641 :
1642 3 : if (strncmp(daemon->storage_handle[i].device_mount_point, mnt_point, (size_t)len) == 0)
1643 3 : return &daemon->storage_handle[i];
1644 : }
1645 :
1646 : return NULL;
1647 : }
|