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