Line data Source code
1 : /*
2 : * SPDX license identifier: MPL-2.0
3 : *
4 : * Copyright (C) 2015 Advanced Driver Information Technology.
5 : * This code is developed by Advanced Driver Information Technology.
6 : * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
7 : *
8 : * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
9 : *
10 : * This Source Code Form is subject to the terms of the
11 : * Mozilla Public License (MPL), v. 2.0.
12 : * If a copy of the MPL was not distributed with this file,
13 : * You can obtain one at http://mozilla.org/MPL/2.0/.
14 : *
15 : * For further information see http://www.covesa.org/.
16 : */
17 :
18 : /*!
19 : * \author
20 : * Christoph Lipka <clipka@jp.adit-jv.com>
21 : * Saya Sugiura <ssugiura@jp.adit-jv.com>
22 : *
23 : * \copyright Copyright © 2015-2018 Advanced Driver Information Technology. \n
24 : * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
25 : *
26 : * \file dlt_gateway.c
27 : */
28 :
29 : #include <stdlib.h>
30 : #include <stdio.h>
31 : #include <string.h>
32 : #include <syslog.h>
33 : #include <arpa/inet.h>
34 : #include <sys/socket.h>
35 : #include <netinet/in.h>
36 : #include <netdb.h>
37 : #include <limits.h>
38 : #include <errno.h>
39 : #include "dlt_gateway.h"
40 : #include "dlt_gateway_internal.h"
41 : #include "dlt_config_file_parser.h"
42 : #include "dlt_common.h"
43 : #include "dlt_log.h"
44 : #include "dlt-daemon_cfg.h"
45 : #include "dlt_daemon_common_cfg.h"
46 : #include "dlt_daemon_event_handler.h"
47 : #include "dlt_daemon_connection.h"
48 : #include "dlt_daemon_client.h"
49 : #include "dlt_daemon_offline_logstorage.h"
50 :
51 : /**
52 : * Check if given string is a valid IP address
53 : *
54 : * @param con DltGatewayConnection to be updated
55 : * @param value string to be tested
56 : * @return Value from DltReturnValue enum
57 : */
58 6 : DLT_STATIC DltReturnValue dlt_gateway_check_ip(DltGatewayConnection* con, char* value)
59 : {
60 6 : if ((con == NULL) || (value == NULL)) {
61 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
62 1 : return DLT_RETURN_WRONG_PARAMETER;
63 : }
64 :
65 : int ret = DLT_RETURN_ERROR;
66 : #ifdef DLT_USE_IPv6
67 : struct sockaddr_in6 sa6;
68 5 : ret = inet_pton(AF_INET6, value, &(sa6.sin6_addr));
69 : #else
70 : struct sockaddr_in sa;
71 : ret = inet_pton(AF_INET, value, &(sa.sin_addr));
72 : #endif
73 :
74 : /* valid IP address */
75 5 : if (ret != 0) {
76 5 : con->ip_address = strdup(value);
77 :
78 5 : if (con->ip_address == NULL) {
79 0 : dlt_log(LOG_ERR, "Cannot copy passive node IP address string\n");
80 0 : return DLT_RETURN_ERROR;
81 : }
82 :
83 : return DLT_RETURN_OK;
84 : } else {
85 0 : dlt_log(LOG_ERR, "IP address is not valid\n");
86 : }
87 :
88 0 : return DLT_RETURN_ERROR;
89 : }
90 :
91 : /**
92 : * Check port number
93 : *
94 : * @param con DltGatewayConnection to be updated
95 : * @param value string to be tested
96 : * @return Value from DltReturnValue enum
97 : */
98 8 : DLT_STATIC DltReturnValue dlt_gateway_check_port(DltGatewayConnection* con, char* value)
99 : {
100 : long int tmp = -1;
101 :
102 8 : if ((con == NULL) || (value == NULL)) {
103 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
104 1 : return DLT_RETURN_WRONG_PARAMETER;
105 : }
106 :
107 7 : errno = 0;
108 7 : tmp = strtol(value, NULL, 10);
109 7 : if ((errno == ERANGE && (tmp == LONG_MAX || tmp == LONG_MIN)) || (errno != 0 && tmp == 0)) {
110 0 : dlt_vlog(LOG_ERR, "%s: cannot convert port number\n", __func__);
111 0 : return DLT_RETURN_ERROR;
112 : }
113 :
114 : /* port ranges for unprivileged applications */
115 7 : if ((tmp > IPPORT_RESERVED) && ((unsigned)tmp <= USHRT_MAX)) {
116 5 : con->port = (int)tmp;
117 5 : return DLT_RETURN_OK;
118 : } else {
119 2 : dlt_log(LOG_ERR, "Port number is invalid\n");
120 : }
121 :
122 2 : return DLT_RETURN_ERROR;
123 : }
124 :
125 : /**
126 : * Check ECU name
127 : *
128 : * @param con DltGatewayConnection to be updated
129 : * @param value string to be used as ECU identifier
130 : * @return Value from DltReturnValue enum
131 : */
132 5 : DLT_STATIC DltReturnValue dlt_gateway_check_ecu(DltGatewayConnection* con, char* value)
133 : {
134 5 : if ((con == NULL) || (value == NULL)) {
135 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
136 1 : return DLT_RETURN_WRONG_PARAMETER;
137 : }
138 :
139 4 : con->ecuid = strdup(value);
140 :
141 4 : if (con->ecuid == NULL)
142 0 : return DLT_RETURN_ERROR;
143 :
144 : return DLT_RETURN_OK;
145 : }
146 :
147 : /**
148 : * Check connection trigger
149 : *
150 : * @param con DltGatewayConnection to be updated
151 : * @param value string to be tested
152 : * @return Value from DltReturnValue enum
153 : */
154 6 : DLT_STATIC DltReturnValue dlt_gateway_check_connect_trigger(DltGatewayConnection* con, char* value)
155 : {
156 6 : if ((con == NULL) || (value == NULL)) {
157 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
158 1 : return DLT_RETURN_WRONG_PARAMETER;
159 : }
160 :
161 5 : if (strncasecmp(value, "OnStartup", strlen("OnStartup")) == 0) {
162 4 : con->trigger = DLT_GATEWAY_ON_STARTUP;
163 1 : } else if (strncasecmp(value, "OnDemand", strlen("OnDemand")) == 0) {
164 0 : con->trigger = DLT_GATEWAY_ON_DEMAND;
165 : } else {
166 1 : dlt_log(LOG_ERR, "Wrong connection trigger state given.\n");
167 1 : con->trigger = DLT_GATEWAY_UNDEFINED;
168 1 : return DLT_RETURN_ERROR;
169 : }
170 :
171 : return DLT_RETURN_OK;
172 : }
173 :
174 : /**
175 : * Check connection timeout value
176 : *
177 : * @param con DltGatewayConnection to be updated
178 : * @param value string to be tested
179 : * @return Value from DltReturnValue enum
180 : */
181 6 : DLT_STATIC DltReturnValue dlt_gateway_check_timeout(DltGatewayConnection* con, char* value)
182 : {
183 6 : if ((con == NULL) || (value == NULL)) {
184 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
185 1 : return DLT_RETURN_WRONG_PARAMETER;
186 : }
187 :
188 5 : con->timeout = (int)strtol(value, NULL, 10);
189 :
190 :
191 5 : if (con->timeout >= 0)
192 4 : return DLT_RETURN_OK;
193 :
194 : return DLT_RETURN_ERROR;
195 : }
196 :
197 : /**
198 : * Check connection interval value in General section
199 : *
200 : * @param con DltGateway to be updated
201 : * @param value string to be tested
202 : * @return Value from DltReturnValue enum
203 : */
204 0 : DLT_STATIC DltReturnValue dlt_gateway_check_interval(DltGateway* gateway, char* value)
205 : {
206 0 : if ((gateway == NULL) || (value == NULL)) {
207 0 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
208 0 : return DLT_RETURN_WRONG_PARAMETER;
209 : }
210 :
211 0 : gateway->interval = (unsigned int)strtol(value, NULL, 10);
212 :
213 0 : if (gateway->interval > 0)
214 0 : return DLT_RETURN_OK;
215 :
216 : return DLT_RETURN_ERROR;
217 : }
218 :
219 : /**
220 : * Check the value for SendSerialHeader
221 : *
222 : * @param con DltGatewayConnection to be updated
223 : * @param value string to be tested
224 : * @return Value from DltReturnValue enum
225 : */
226 5 : DLT_STATIC DltReturnValue dlt_gateway_check_send_serial(DltGatewayConnection* con, char* value)
227 : {
228 5 : if ((con == NULL) || (value == NULL)) {
229 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
230 1 : return DLT_RETURN_WRONG_PARAMETER;
231 : }
232 :
233 4 : con->send_serial = !!((int)strtol(value, NULL, 10));
234 :
235 4 : return DLT_RETURN_OK;
236 : }
237 :
238 : /**
239 : * Allocate passive control messages
240 : *
241 : * @param con DltGatewayConnection to be updated
242 : * @return Value from DltReturnValue enum
243 : */
244 15 : DLT_STATIC DltReturnValue dlt_gateway_allocate_control_messages(DltGatewayConnection* con)
245 : {
246 15 : if (con == NULL) {
247 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
248 1 : return DLT_RETURN_WRONG_PARAMETER;
249 : }
250 :
251 14 : if (con->p_control_msgs == NULL) {
252 6 : con->p_control_msgs = calloc(1, sizeof(DltPassiveControlMessage));
253 :
254 6 : if (!con->p_control_msgs) {
255 0 : dlt_log(LOG_ERR, "Passive Control Message could not be allocated\n");
256 0 : return DLT_RETURN_ERROR;
257 : }
258 : } else {
259 8 : con->p_control_msgs->next = calloc(1, sizeof(DltPassiveControlMessage));
260 :
261 8 : if (!con->p_control_msgs->next) {
262 0 : dlt_log(LOG_ERR, "Passive Control Message could not be allocated\n");
263 0 : return DLT_RETURN_ERROR;
264 : }
265 :
266 8 : con->p_control_msgs = con->p_control_msgs->next;
267 : }
268 :
269 : return DLT_RETURN_OK;
270 : }
271 :
272 : /**
273 : * Check the specified control messages identifier
274 : *
275 : * @param con DltGatewayConnection to be updated
276 : * @param value string to be tested
277 : * @return Value from DltReturnValue enum
278 : */
279 5 : DLT_STATIC DltReturnValue dlt_gateway_check_control_messages(DltGatewayConnection* con, char* value)
280 : {
281 : /* list of allowed clients given */
282 : char* token = NULL;
283 5 : char* rest = NULL;
284 : DltPassiveControlMessage* head = NULL;
285 :
286 5 : if ((con == NULL) || (value == NULL)) {
287 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
288 1 : return DLT_RETURN_WRONG_PARAMETER;
289 : }
290 :
291 4 : if (strlen(value) == 0)
292 : return DLT_RETURN_OK;
293 :
294 : /* set on startup control msg id and interval*/
295 4 : token = strtok_r(value, ",", &rest);
296 :
297 15 : while (token != NULL) {
298 11 : if (dlt_gateway_allocate_control_messages(con) != DLT_RETURN_OK) {
299 0 : dlt_log(LOG_ERR, "Passive Control Message could not be allocated\n");
300 0 : return DLT_RETURN_ERROR;
301 : }
302 :
303 11 : con->p_control_msgs->id = (uint32_t)strtol(token, NULL, 16);
304 11 : con->p_control_msgs->user_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT;
305 11 : con->p_control_msgs->type = CONTROL_MESSAGE_ON_STARTUP;
306 11 : con->p_control_msgs->req = CONTROL_MESSAGE_NOT_REQUESTED;
307 11 : con->p_control_msgs->interval = 0;
308 :
309 11 : if (head == NULL)
310 : head = con->p_control_msgs;
311 :
312 11 : if ((errno == EINVAL) || (errno == ERANGE)) {
313 0 : dlt_vlog(LOG_ERR, "Control message ID is not an integer: %s\n", token);
314 0 : return DLT_RETURN_ERROR;
315 11 : } else if (
316 : (con->p_control_msgs->id < DLT_SERVICE_ID_SET_LOG_LEVEL)
317 11 : || (con->p_control_msgs->id >= DLT_SERVICE_ID_LAST_ENTRY)) {
318 0 : dlt_vlog(LOG_ERR, "Control message ID is not valid: %s\n", token);
319 0 : return DLT_RETURN_ERROR;
320 : }
321 :
322 11 : token = strtok_r(NULL, ",", &rest);
323 : }
324 :
325 : /* get back to head */
326 4 : con->p_control_msgs = head;
327 4 : con->head = head;
328 :
329 4 : return DLT_RETURN_OK;
330 : }
331 :
332 : /**
333 : * Check the specified periodic control messages identifier
334 : *
335 : * @param con DltGatewayConnection to be updated
336 : * @param value string to be tested
337 : * @return Value from DltReturnValue enum
338 : */
339 2 : DLT_STATIC DltReturnValue dlt_gateway_check_periodic_control_messages(DltGatewayConnection* con, char* value)
340 : {
341 : char* token = NULL;
342 2 : char* rest = NULL;
343 : DltPassiveControlMessage* head = NULL;
344 :
345 2 : if ((con == NULL) || (value == NULL)) {
346 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
347 1 : return DLT_RETURN_WRONG_PARAMETER;
348 : }
349 :
350 1 : if (strlen(value) == 0)
351 : return DLT_RETURN_OK;
352 :
353 : /* store head address */
354 1 : head = con->p_control_msgs;
355 :
356 : /* set periodic control msg id and interval*/
357 1 : token = strtok_r(value, ",", &rest);
358 :
359 3 : while (token != NULL) {
360 : char* p_token = NULL;
361 2 : char* p_rest = NULL;
362 : uint32_t id = 0;
363 :
364 2 : p_token = strtok_r(token, ":", &p_rest);
365 :
366 2 : if ((p_token != NULL) && (strlen(p_token) != 0)) {
367 2 : id = (uint32_t)strtol(p_token, NULL, 16);
368 :
369 : /* get back to head */
370 2 : con->p_control_msgs = head;
371 :
372 : /* check if there is already id set in p_control_msgs */
373 3 : while (con->p_control_msgs != NULL) {
374 1 : if (con->p_control_msgs->id == id) {
375 0 : con->p_control_msgs->type = CONTROL_MESSAGE_BOTH;
376 0 : con->p_control_msgs->interval = (unsigned int)strtol(p_rest, NULL, 10);
377 :
378 0 : if (con->p_control_msgs->interval == 0)
379 0 : dlt_vlog(
380 : LOG_WARNING, "%s interval is %d. It won't be send periodically.\n",
381 : dlt_get_service_name(con->p_control_msgs->id), con->p_control_msgs->interval);
382 :
383 : break;
384 : }
385 :
386 1 : con->p_control_msgs = con->p_control_msgs->next;
387 : }
388 :
389 : /* if the id is not added yet, p_control_msgs supposed to be NULL */
390 2 : if (con->p_control_msgs == NULL) {
391 : /* get back to head */
392 2 : con->p_control_msgs = head;
393 :
394 : /* go to last pointer */
395 2 : while (con->p_control_msgs != NULL) {
396 1 : if (con->p_control_msgs->next == NULL)
397 : break;
398 :
399 0 : con->p_control_msgs = con->p_control_msgs->next;
400 : }
401 :
402 2 : if (dlt_gateway_allocate_control_messages(con) != DLT_RETURN_OK) {
403 0 : dlt_log(LOG_ERR, "Passive Control Message could not be allocated\n");
404 0 : return DLT_RETURN_ERROR;
405 : }
406 :
407 2 : con->p_control_msgs->id = id;
408 2 : con->p_control_msgs->user_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT;
409 2 : con->p_control_msgs->type = CONTROL_MESSAGE_PERIODIC;
410 2 : con->p_control_msgs->req = CONTROL_MESSAGE_NOT_REQUESTED;
411 2 : con->p_control_msgs->interval = (unsigned int)strtol(p_rest, NULL, 10);
412 :
413 2 : if (con->p_control_msgs->interval == 0)
414 0 : dlt_vlog(
415 : LOG_WARNING, "%s interval is %d. It won't be send periodically.\n",
416 : dlt_get_service_name(con->p_control_msgs->id), con->p_control_msgs->interval);
417 :
418 2 : if (head == NULL)
419 1 : head = con->p_control_msgs;
420 : }
421 : }
422 :
423 2 : if ((errno == EINVAL) || (errno == ERANGE)) {
424 0 : dlt_vlog(LOG_ERR, "Control message ID is not an integer: %s\n", p_token);
425 0 : return DLT_RETURN_ERROR;
426 2 : } else if (
427 2 : (con->p_control_msgs->id < DLT_SERVICE_ID_SET_LOG_LEVEL)
428 2 : || (con->p_control_msgs->id >= DLT_SERVICE_ID_LAST_ENTRY)) {
429 0 : dlt_vlog(LOG_ERR, "Control message ID is not valid: %s\n", p_token);
430 0 : return DLT_RETURN_ERROR;
431 : }
432 :
433 2 : token = strtok_r(NULL, ",", &rest);
434 : }
435 :
436 : /* get back to head */
437 1 : con->p_control_msgs = head;
438 1 : con->head = head;
439 :
440 1 : return DLT_RETURN_OK;
441 : }
442 :
443 : /**
444 : * Expected entries for a passive node configuration
445 : * Caution: after changing entries here,
446 : * dlt_gateway_check_param needs to be updated as well
447 : * */
448 : DLT_STATIC DltGatewayConf configuration_entries[GW_CONF_COUNT] = {
449 : [GW_CONF_IP_ADDRESS] = {.key = "IPaddress", .func = dlt_gateway_check_ip, .is_opt = 0},
450 : [GW_CONF_PORT] = {.key = "Port", .func = dlt_gateway_check_port, .is_opt = 1},
451 : [GW_CONF_ECUID] = {.key = "EcuID", .func = dlt_gateway_check_ecu, .is_opt = 0},
452 : [GW_CONF_CONNECT] = {.key = "Connect", .func = dlt_gateway_check_connect_trigger, .is_opt = 1},
453 : [GW_CONF_TIMEOUT] = {.key = "Timeout", .func = dlt_gateway_check_timeout, .is_opt = 0},
454 : [GW_CONF_SEND_CONTROL] = {.key = "SendControl", .func = dlt_gateway_check_control_messages, .is_opt = 1},
455 : [GW_CONF_SEND_PERIODIC_CONTROL] =
456 : {.key = "SendPeriodicControl", .func = dlt_gateway_check_periodic_control_messages, .is_opt = 1},
457 : [GW_CONF_SEND_SERIAL_HEADER] = {.key = "SendSerialHeader", .func = dlt_gateway_check_send_serial, .is_opt = 1}};
458 :
459 : DLT_STATIC DltGatewayGeneralConf general_entries[GW_CONF_COUNT] = {
460 : [GW_CONF_GENERAL_INTERVAL] = {.key = "Interval", .func = dlt_gateway_check_interval, .is_opt = 1}};
461 :
462 : #define DLT_GATEWAY_NUM_PROPERTIES_MAX GW_CONF_COUNT
463 :
464 : /**
465 : * Check if gateway connection general configuration parameter is valid.
466 : *
467 : * @param gateway DltGateway
468 : * @param ctype DltGatwayGeneralConnection property
469 : * @param value specified property value from configuration file
470 : * @return Value from DltReturnValue enum
471 : */
472 : DLT_STATIC DltReturnValue
473 0 : dlt_gateway_check_general_param(DltGateway* gateway, DltGatewayGeneralConfType ctype, char* value)
474 : {
475 0 : if ((gateway == NULL) || (value == NULL)) {
476 0 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
477 0 : return DLT_RETURN_WRONG_PARAMETER;
478 : }
479 :
480 0 : if (ctype < GW_CONF_GENEREL_COUNT)
481 0 : return general_entries[ctype].func(gateway, value);
482 :
483 : return DLT_RETURN_ERROR;
484 : }
485 :
486 : /**
487 : * Check if gateway connection configuration parameter is valid.
488 : *
489 : * @param gateway DltGateway
490 : * @param con DltGatewayConnection
491 : * @param ctype DltGatwayConnection property
492 : * @param value specified property value from configuration file
493 : * @return Value from DltReturnValue enum
494 : */
495 : DLT_STATIC DltReturnValue
496 25 : dlt_gateway_check_param(DltGateway* gateway, DltGatewayConnection* con, DltGatewayConfType ctype, char* value)
497 : {
498 25 : if ((gateway == NULL) || (con == NULL) || (value == NULL)) {
499 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
500 1 : return DLT_RETURN_WRONG_PARAMETER;
501 : }
502 :
503 24 : if (ctype < GW_CONF_COUNT)
504 24 : return configuration_entries[ctype].func(con, value);
505 :
506 : return DLT_RETURN_ERROR;
507 : }
508 :
509 : /**
510 : * Store gateway connection in internal data structure
511 : *
512 : * @param gateway DltGatway
513 : * @param tmp DltGatewayConnection
514 : * @param verbose verbose flag
515 : * @return 0 on success, -1 otherwise
516 : */
517 6 : int dlt_gateway_store_connection(DltGateway* gateway, DltGatewayConnection* tmp, int verbose)
518 : {
519 : int i = 0;
520 :
521 6 : PRINT_FUNCTION_VERBOSE(verbose);
522 :
523 6 : if ((gateway == NULL) || (tmp == NULL)) {
524 2 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
525 2 : return DLT_RETURN_WRONG_PARAMETER;
526 : }
527 :
528 : /* find next free entry in connection array */
529 4 : while (i < gateway->num_connections) {
530 4 : if (gateway->connections[i].status == DLT_GATEWAY_UNINITIALIZED)
531 : break;
532 :
533 0 : i++;
534 : }
535 :
536 : /* store values */
537 4 : gateway->connections[i].ip_address = strdup(tmp->ip_address);
538 4 : gateway->connections[i].ecuid = strdup(tmp->ecuid);
539 4 : gateway->connections[i].sock_domain = tmp->sock_domain;
540 4 : gateway->connections[i].sock_type = tmp->sock_type;
541 4 : gateway->connections[i].sock_protocol = tmp->sock_protocol;
542 4 : gateway->connections[i].port = tmp->port;
543 4 : gateway->connections[i].trigger = tmp->trigger;
544 4 : gateway->connections[i].timeout = tmp->timeout;
545 4 : gateway->connections[i].handle = 0;
546 4 : gateway->connections[i].status = DLT_GATEWAY_INITIALIZED;
547 4 : gateway->connections[i].p_control_msgs = tmp->p_control_msgs;
548 4 : gateway->connections[i].head = tmp->head;
549 4 : gateway->connections[i].send_serial = tmp->send_serial;
550 :
551 4 : if (dlt_client_init_port(&gateway->connections[i].client, gateway->connections[i].port, verbose) != 0) {
552 0 : free(gateway->connections[i].ip_address);
553 0 : gateway->connections[i].ip_address = NULL;
554 0 : free(gateway->connections[i].ecuid);
555 0 : gateway->connections[i].ecuid = NULL;
556 0 : free(gateway->connections[i].p_control_msgs);
557 0 : gateway->connections[i].p_control_msgs = NULL;
558 0 : dlt_log(LOG_CRIT, "dlt_client_init_port() failed for gateway connection\n");
559 0 : return DLT_RETURN_ERROR;
560 : }
561 :
562 : /* setup DltClient Structure */
563 4 : if (dlt_client_set_server_ip(&gateway->connections[i].client, gateway->connections[i].ip_address) == -1) {
564 0 : dlt_log(LOG_ERR, "dlt_client_set_server_ip() failed for gateway connection \n");
565 0 : return DLT_RETURN_ERROR;
566 : }
567 :
568 : return DLT_RETURN_OK;
569 : }
570 :
571 : /**
572 : * Read configuration file and initialize connection data structures
573 : *
574 : * @param gateway DltGateway
575 : * @param config_file Gateway configuration
576 : * @param verbose verbose flag
577 : * @return 0 on success, -1 otherwise
578 : */
579 4 : int dlt_gateway_configure(DltGateway* gateway, char* config_file, int verbose)
580 : {
581 : int ret = 0;
582 : int i = 0;
583 : DltConfigFile* file = NULL;
584 4 : int num_sections = 0;
585 :
586 4 : PRINT_FUNCTION_VERBOSE(verbose);
587 :
588 4 : if ((gateway == NULL) || (config_file == 0) || (config_file[0] == '\0')) {
589 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
590 1 : return DLT_RETURN_WRONG_PARAMETER;
591 : }
592 :
593 : /* read configuration file */
594 3 : file = dlt_config_file_init(config_file);
595 3 : if (file == NULL) {
596 : return DLT_RETURN_ERROR;
597 : }
598 :
599 : /* get number of entries and allocate memory to store information */
600 3 : ret = dlt_config_file_get_num_sections(file, &num_sections);
601 3 : if (ret != 0) {
602 0 : dlt_config_file_release(file);
603 0 : dlt_log(LOG_ERR, "Invalid number of sections in configuration file\n");
604 0 : return DLT_RETURN_ERROR;
605 : }
606 :
607 3 : ret = dlt_config_file_check_section_name_exists(file, DLT_GATEWAY_GENERAL_SECTION_NAME);
608 3 : if (ret == -1) {
609 : /*
610 : * No General section in configuration file.
611 : * Try to use default for interval.
612 : */
613 3 : gateway->num_connections = num_sections;
614 3 : dlt_vlog(
615 : LOG_WARNING, "Missing General section in gateway. Using default interval %d (secs)\n", gateway->interval);
616 : } else {
617 : /*
618 : * Since the General section is also counted in num_sections,
619 : * so number of connections must be number of sections - 1.
620 : */
621 0 : gateway->num_connections = num_sections - 1;
622 : }
623 :
624 3 : gateway->connections = calloc((size_t)gateway->num_connections, sizeof(DltGatewayConnection));
625 :
626 3 : if (gateway->connections == NULL) {
627 0 : dlt_config_file_release(file);
628 0 : dlt_log(LOG_CRIT, "Memory allocation for gateway connections failed\n");
629 0 : return DLT_RETURN_ERROR;
630 : }
631 :
632 6 : for (i = 0; i < num_sections; i++) {
633 : DltGatewayConnection tmp;
634 : int invalid = 0;
635 : DltGatewayConfType j = 0;
636 : DltGatewayGeneralConfType g = 0;
637 3 : char section[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = {'\0'};
638 3 : char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = {'\0'};
639 :
640 : memset(&tmp, 0, sizeof(tmp));
641 :
642 : /* Set default */
643 3 : tmp.send_serial = gateway->send_serial;
644 3 : tmp.port = DLT_DAEMON_TCP_PORT;
645 :
646 3 : ret = dlt_config_file_get_section_name(file, i, section);
647 3 : if (ret != 0) {
648 0 : dlt_log(LOG_WARNING, "Get section name failed\n");
649 0 : continue;
650 : }
651 :
652 3 : if (strncmp(section, DLT_GATEWAY_GENERAL_SECTION_NAME, sizeof(DLT_GATEWAY_GENERAL_SECTION_NAME)) == 0) {
653 0 : for (g = 0; g < GW_CONF_GENEREL_COUNT; g++) {
654 0 : ret = dlt_config_file_get_value(file, section, general_entries[g].key, value);
655 :
656 0 : if ((ret != 0) && general_entries[g].is_opt) {
657 : /* Use default values for this key */
658 0 : dlt_vlog(LOG_WARNING, "Using default for %s.\n", general_entries[g].key);
659 0 : continue;
660 : } else if (ret != 0) {
661 0 : dlt_vlog(LOG_WARNING, "Missing configuration for %s.\n", general_entries[g].key);
662 0 : break;
663 : }
664 :
665 : /* check value and store general configuration */
666 0 : ret = dlt_gateway_check_general_param(gateway, g, value);
667 :
668 0 : if (ret != 0)
669 0 : dlt_vlog(
670 : LOG_ERR, "Configuration %s = %s is invalid. Using default.\n", general_entries[g].key, value);
671 : }
672 : } else {
673 27 : for (j = 0; j < GW_CONF_COUNT; j++) {
674 24 : ret = dlt_config_file_get_value(file, section, configuration_entries[j].key, value);
675 :
676 24 : if ((ret != 0) && configuration_entries[j].is_opt) {
677 : /* Use default values for this key */
678 3 : dlt_vlog(LOG_WARNING, "Using default for %s.\n", configuration_entries[j].key);
679 3 : continue;
680 : } else if (ret != 0) {
681 0 : dlt_vlog(LOG_WARNING, "Missing configuration for %s.\n", configuration_entries[j].key);
682 : invalid = 1;
683 0 : break;
684 : }
685 :
686 : /* check value and store temporary */
687 21 : ret = dlt_gateway_check_param(gateway, &tmp, j, value);
688 :
689 21 : if (ret != 0)
690 0 : dlt_vlog(
691 : LOG_ERR,
692 : "Configuration %s = %s is invalid.\n"
693 : "Using default.\n",
694 : configuration_entries[j].key, value);
695 : }
696 :
697 3 : if (!tmp.ip_address) {
698 : invalid = 1;
699 : }
700 :
701 3 : if (invalid) {
702 0 : dlt_vlog(
703 : LOG_ERR,
704 : "%s configuration is invalid.\n"
705 : "Ignoring.\n",
706 : section);
707 : } else {
708 3 : ret = dlt_gateway_store_connection(gateway, &tmp, verbose);
709 :
710 3 : if (ret != 0)
711 0 : dlt_log(LOG_ERR, "Storing gateway connection data failed\n");
712 : }
713 : }
714 :
715 : /* strdup used inside some get_value function */
716 3 : if (tmp.ecuid != NULL) {
717 3 : free(tmp.ecuid);
718 : tmp.ecuid = NULL;
719 : }
720 3 : if (tmp.ip_address != NULL) {
721 3 : free(tmp.ip_address);
722 : tmp.ip_address = NULL;
723 : }
724 : }
725 :
726 3 : dlt_config_file_release(file);
727 3 : return ret;
728 : }
729 :
730 3 : int dlt_gateway_init(DltDaemonLocal* daemon_local, int verbose)
731 : {
732 3 : PRINT_FUNCTION_VERBOSE(verbose);
733 :
734 3 : if (daemon_local == NULL) {
735 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
736 1 : return DLT_RETURN_WRONG_PARAMETER;
737 : }
738 :
739 2 : DltGateway* gateway = &daemon_local->pGateway;
740 :
741 : if (gateway != NULL) {
742 : /* Get default value from daemon_local */
743 2 : gateway->send_serial = daemon_local->flags.lflag;
744 2 : gateway->interval = DLT_GATEWAY_TIMER_DEFAULT_INTERVAL;
745 :
746 2 : if (dlt_gateway_configure(gateway, daemon_local->flags.gatewayConfigFile, verbose) != 0) {
747 0 : dlt_log(LOG_ERR, "Gateway initialization failed\n");
748 0 : return DLT_RETURN_ERROR;
749 : }
750 : } else {
751 : dlt_log(LOG_CRIT, "Pointer to Gateway structure is NULL\n");
752 : return DLT_RETURN_ERROR;
753 : }
754 :
755 : /* ignore return value */
756 2 : dlt_gateway_establish_connections(gateway, daemon_local, verbose);
757 :
758 2 : return DLT_RETURN_OK;
759 : }
760 :
761 2 : void dlt_gateway_deinit(DltGateway* gateway, int verbose)
762 : {
763 : DltPassiveControlMessage* msg;
764 : int i = 0;
765 :
766 2 : if (gateway == NULL) {
767 0 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
768 0 : return;
769 : }
770 :
771 2 : PRINT_FUNCTION_VERBOSE(verbose);
772 :
773 3 : for (i = 0; i < gateway->num_connections; i++) {
774 1 : DltGatewayConnection* c = &gateway->connections[i];
775 1 : dlt_client_cleanup(&c->client, verbose);
776 1 : free(c->ip_address);
777 1 : c->ip_address = NULL;
778 1 : free(c->ecuid);
779 1 : c->ecuid = NULL;
780 :
781 3 : while (c->p_control_msgs != NULL) {
782 2 : msg = c->p_control_msgs->next;
783 2 : free(c->p_control_msgs);
784 2 : c->p_control_msgs = msg;
785 : }
786 : }
787 :
788 2 : free(gateway->connections);
789 2 : gateway->connections = NULL;
790 : }
791 :
792 : /**
793 : * If connection to passive node established, add to event loop
794 : *
795 : * @param daemon_local DltDaemonLocal
796 : * @param con DltGatewayConnection
797 : * @param verbose verbose flag
798 : * @return 0 on success, -1 otherwise
799 : */
800 2 : DLT_STATIC int dlt_gateway_add_to_event_loop(DltDaemonLocal* daemon_local, DltGatewayConnection* con, int verbose)
801 : {
802 : DltPassiveControlMessage* control_msg = NULL;
803 : unsigned int sendtime = 1;
804 :
805 2 : if ((daemon_local == NULL) || (con == NULL)) {
806 0 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
807 0 : return DLT_RETURN_WRONG_PARAMETER;
808 : }
809 :
810 : /* connection to passive node established, add to event loop */
811 2 : con->status = DLT_GATEWAY_CONNECTED;
812 2 : con->reconnect_cnt = 0;
813 2 : con->timeout_cnt = 0;
814 2 : con->sendtime_cnt = 0;
815 :
816 : /* setup dlt connection and add to poll event loop here */
817 2 : if (dlt_connection_create(daemon_local, &daemon_local->pEvent, con->client.sock, POLLIN, DLT_CONNECTION_GATEWAY)
818 : != 0) {
819 0 : dlt_log(LOG_ERR, "Gateway connection creation failed\n");
820 0 : return DLT_RETURN_ERROR;
821 : }
822 :
823 : /* immediately send configured control messages */
824 2 : control_msg = con->p_control_msgs;
825 :
826 6 : while (control_msg != NULL) {
827 4 : if ((control_msg->type == CONTROL_MESSAGE_ON_STARTUP) || (control_msg->type == CONTROL_MESSAGE_BOTH)) {
828 4 : if (dlt_gateway_send_control_message(con, control_msg, NULL, verbose) == DLT_RETURN_OK)
829 4 : control_msg->req = CONTROL_MESSAGE_REQUESTED;
830 : }
831 :
832 : /* multiply periodic sending time */
833 4 : if (((control_msg->type == CONTROL_MESSAGE_PERIODIC) || (control_msg->type == CONTROL_MESSAGE_BOTH))
834 0 : && (control_msg->interval > 0))
835 0 : sendtime *= control_msg->interval;
836 :
837 4 : control_msg = control_msg->next;
838 : }
839 :
840 : /* set periodic sending time */
841 2 : con->sendtime = sendtime;
842 2 : con->sendtime_cnt = con->sendtime;
843 :
844 2 : return DLT_RETURN_OK;
845 : }
846 :
847 5 : int dlt_gateway_establish_connections(DltGateway* gateway, DltDaemonLocal* daemon_local, int verbose)
848 : {
849 : int i = 0;
850 : int ret = 0;
851 :
852 5 : PRINT_FUNCTION_VERBOSE(verbose);
853 :
854 5 : if ((gateway == NULL) || (daemon_local == NULL)) {
855 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
856 1 : return DLT_RETURN_WRONG_PARAMETER;
857 : }
858 :
859 8 : for (i = 0; i < gateway->num_connections; i++) {
860 4 : DltGatewayConnection* con = &(gateway->connections[i]);
861 : DltPassiveControlMessage* control_msg = NULL;
862 :
863 4 : if ((con->status != DLT_GATEWAY_CONNECTED) && (con->trigger != DLT_GATEWAY_ON_DEMAND)
864 4 : && (con->trigger != DLT_GATEWAY_DISABLED)) {
865 4 : ret = dlt_client_connect(&con->client, verbose);
866 :
867 4 : if (ret == 0) {
868 : /* setup dlt connection and add to poll event loop here */
869 2 : if (dlt_gateway_add_to_event_loop(daemon_local, con, verbose) != DLT_RETURN_OK) {
870 0 : dlt_log(LOG_ERR, "Gateway connection creation failed\n");
871 0 : return DLT_RETURN_ERROR;
872 : }
873 : } else {
874 2 : dlt_log(LOG_DEBUG, "Passive Node is not up. Connection failed.\n");
875 :
876 2 : con->timeout_cnt++;
877 :
878 2 : if (con->timeout > 0) {
879 0 : if (con->timeout_cnt > con->timeout) {
880 0 : con->trigger = DLT_GATEWAY_DISABLED;
881 0 : dlt_log(
882 : LOG_WARNING,
883 : "Passive Node connection retry timed out. "
884 : "Give up.\n");
885 : }
886 2 : } else if (con->timeout == 0) {
887 2 : dlt_vlog(LOG_DEBUG, "Retried [%d] times\n", con->timeout_cnt);
888 : }
889 : }
890 0 : } else if ((con->status == DLT_GATEWAY_CONNECTED) && (con->trigger != DLT_GATEWAY_DISABLED)) {
891 : /* setup dlt connection and add to poll event loop here */
892 0 : if (dlt_connection_create(
893 : daemon_local, &daemon_local->pEvent, con->client.sock, POLLIN, DLT_CONNECTION_GATEWAY)
894 : != 0) {
895 0 : dlt_log(LOG_ERR, "Gateway connection creation failed\n");
896 0 : return DLT_RETURN_ERROR;
897 : }
898 :
899 : /* immediately send periodic configured control messages */
900 0 : control_msg = con->p_control_msgs;
901 :
902 0 : while (control_msg != NULL) {
903 0 : if ((control_msg->type == CONTROL_MESSAGE_PERIODIC) || (control_msg->type == CONTROL_MESSAGE_BOTH)) {
904 0 : if (dlt_gateway_send_control_message(con, control_msg, NULL, verbose) == DLT_RETURN_OK)
905 0 : control_msg->req = CONTROL_MESSAGE_REQUESTED;
906 : }
907 :
908 0 : control_msg = control_msg->next;
909 : }
910 :
911 : /* check sendtime counter */
912 0 : if (con->sendtime_cnt > 0)
913 0 : con->sendtime_cnt--;
914 :
915 0 : if (con->sendtime_cnt == 0)
916 0 : con->sendtime_cnt = con->sendtime;
917 : }
918 : }
919 :
920 : return DLT_RETURN_OK;
921 : }
922 :
923 5 : DltReceiver* dlt_gateway_get_connection_receiver(DltGateway* gateway, int fd)
924 : {
925 : int i = 0;
926 :
927 5 : if (gateway == NULL) {
928 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
929 1 : return NULL;
930 : }
931 :
932 5 : for (i = 0; i < gateway->num_connections; i++) {
933 4 : DltGatewayConnection* c = &gateway->connections[i];
934 :
935 4 : if ((c->status == DLT_GATEWAY_CONNECTED) && (c->client.sock == fd))
936 3 : return &c->client.receiver;
937 : }
938 :
939 : return NULL;
940 : }
941 :
942 : /**
943 : * Parse GET_LOG_INFO
944 : *
945 : * @param daemon DltDaemon
946 : * @param ecu Ecu ID
947 : * @param msg DltMessage
948 : * @param req 1 if requested from gateway, 0 otherwise
949 : * @param verbose verbose flag
950 : * @return Value from DltReturnValue enum
951 : */
952 : DLT_STATIC DltReturnValue
953 2 : dlt_gateway_parse_get_log_info(DltDaemon* daemon, char* ecu, DltMessage* msg, int req, int verbose)
954 : {
955 2 : char resp_text[DLT_RECEIVE_BUFSIZE] = {'\0'};
956 : DltServiceGetLogInfoResponse* resp = NULL;
957 : AppIDsType app;
958 : ContextIDsInfoType con;
959 : int i = 0;
960 : int j = 0;
961 :
962 2 : PRINT_FUNCTION_VERBOSE(verbose);
963 :
964 2 : if ((msg == NULL) || (msg->databuffer == NULL)) {
965 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
966 1 : return DLT_RETURN_WRONG_PARAMETER;
967 : }
968 :
969 1 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceGetLogInfoResponse)) < 0)
970 : return DLT_RETURN_ERROR;
971 :
972 : /* if the request was send from gateway, clear all application and context list */
973 1 : if (req == CONTROL_MESSAGE_REQUESTED) {
974 : /* clear application list */
975 0 : if (dlt_daemon_applications_clear(daemon, ecu, verbose) == DLT_RETURN_ERROR) {
976 0 : dlt_log(LOG_ERR, "Cannot clear applications list\n");
977 0 : return DLT_RETURN_ERROR;
978 : }
979 :
980 : /* clear context list */
981 0 : if (dlt_daemon_contexts_clear(daemon, ecu, verbose) == DLT_RETURN_ERROR) {
982 0 : dlt_log(LOG_ERR, "Cannot clear contexts list\n");
983 0 : return DLT_RETURN_ERROR;
984 : }
985 : }
986 :
987 : /* check response */
988 1 : if (dlt_message_payload(msg, resp_text, DLT_RECEIVE_BUFSIZE, DLT_OUTPUT_ASCII, 0) != DLT_RETURN_OK) {
989 0 : dlt_log(LOG_ERR, "GET_LOG_INFO payload failed\n");
990 0 : return DLT_RETURN_ERROR;
991 : }
992 :
993 : /* prepare pointer to message request */
994 1 : resp = (DltServiceGetLogInfoResponse*)calloc(1, sizeof(DltServiceGetLogInfoResponse));
995 :
996 1 : if (resp == NULL) {
997 0 : dlt_log(LOG_ERR, "Get Log Info Response could not be allocated\n");
998 0 : return DLT_RETURN_ERROR;
999 : }
1000 :
1001 1 : if (dlt_set_loginfo_parse_service_id(resp_text, &resp->service_id, &resp->status) != DLT_RETURN_OK) {
1002 0 : dlt_log(LOG_ERR, "Parsing GET_LOG_INFO failed\n");
1003 0 : dlt_client_cleanup_get_log_info(resp);
1004 0 : return DLT_RETURN_ERROR;
1005 : }
1006 :
1007 1 : if (dlt_client_parse_get_log_info_resp_text(resp, resp_text) != DLT_RETURN_OK) {
1008 0 : dlt_log(LOG_ERR, "Parsing GET_LOG_INFO failed\n");
1009 0 : dlt_client_cleanup_get_log_info(resp);
1010 0 : return DLT_RETURN_ERROR;
1011 : }
1012 :
1013 2 : for (i = 0; i < resp->log_info_type.count_app_ids; i++) {
1014 1 : app = resp->log_info_type.app_ids[i];
1015 :
1016 : /* add application */
1017 1 : if (dlt_daemon_application_add(daemon, app.app_id, 0, app.app_description, -1, ecu, verbose) == 0) {
1018 0 : dlt_vlog(LOG_WARNING, "%s: dlt_daemon_application_add failed\n", __func__);
1019 0 : dlt_client_cleanup_get_log_info(resp);
1020 0 : return DLT_RETURN_ERROR;
1021 : }
1022 :
1023 2 : for (j = 0; j < app.count_context_ids; j++) {
1024 1 : con = app.context_id_info[j];
1025 :
1026 : /* add context */
1027 1 : if (dlt_daemon_context_add(
1028 1 : daemon, app.app_id, con.context_id, (int8_t)con.log_level, (int8_t)con.trace_status, 0, -1,
1029 : con.context_description, ecu, verbose)
1030 : == 0) {
1031 0 : dlt_vlog(LOG_WARNING, "%s: dlt_daemon_context_add failed for %4s\n", __func__, app.app_id);
1032 0 : dlt_client_cleanup_get_log_info(resp);
1033 0 : return DLT_RETURN_ERROR;
1034 : }
1035 : }
1036 : }
1037 :
1038 : /* free response */
1039 1 : dlt_client_cleanup_get_log_info(resp);
1040 :
1041 1 : return DLT_RETURN_OK;
1042 : }
1043 :
1044 : /**
1045 : * Parse GET_DEFAULT_LOG_LEVEL
1046 : *
1047 : * @param daemon DltDaemon
1048 : * @param daemon_local DltDaemonLocal
1049 : * @param ecu Ecu ID
1050 : * @param msg DltMessage
1051 : * @param verbose verbose flag
1052 : * @return 0 on success, -1 otherwise
1053 : */
1054 0 : DLT_STATIC int dlt_gateway_parse_get_default_log_level(
1055 : DltDaemon* daemon, DltDaemonLocal* daemon_local, char* ecu, DltMessage* msg, int verbose)
1056 : {
1057 : DltServiceGetDefaultLogLevelResponse* resp = NULL;
1058 : DltGatewayConnection* con = NULL;
1059 :
1060 0 : PRINT_FUNCTION_VERBOSE(verbose);
1061 :
1062 0 : if ((daemon == NULL) || (daemon_local == NULL)) {
1063 0 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
1064 0 : return DLT_RETURN_WRONG_PARAMETER;
1065 : }
1066 :
1067 0 : if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceGetDefaultLogLevelResponse)) < 0) {
1068 0 : dlt_log(LOG_ERR, "Received data incomplete.\n");
1069 0 : return DLT_RETURN_ERROR;
1070 : }
1071 :
1072 : /* prepare pointer to message request */
1073 0 : resp = (DltServiceGetDefaultLogLevelResponse*)(msg->databuffer);
1074 :
1075 0 : con = dlt_gateway_get_connection(&daemon_local->pGateway, ecu, verbose);
1076 :
1077 0 : if (con == NULL) {
1078 0 : dlt_vlog(LOG_ERR, "No information about passive ECU: %s\n", ecu);
1079 :
1080 0 : return DLT_RETURN_ERROR;
1081 : }
1082 :
1083 0 : con->default_log_level = resp->log_level;
1084 :
1085 0 : return DLT_RETURN_OK;
1086 : }
1087 :
1088 : /**
1089 : * Service offline logstorage
1090 : *
1091 : * @param daemon DltDaemon
1092 : * @param daemon_local DltDaemonLocal
1093 : * @param verbose int
1094 : * @return 0 on success, -1 otherwise
1095 : */
1096 0 : DLT_STATIC int dlt_gateway_control_service_logstorage(DltDaemon* daemon, DltDaemonLocal* daemon_local, int verbose)
1097 : {
1098 : unsigned int connection_type = 0;
1099 : int i = 0;
1100 :
1101 0 : if (daemon_local->flags.offlineLogstorageMaxDevices <= 0) {
1102 0 : dlt_log(LOG_INFO, "Logstorage functionality not enabled or MAX device set is 0\n");
1103 0 : return DLT_RETURN_ERROR;
1104 : }
1105 :
1106 0 : for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) {
1107 0 : connection_type = daemon->storage_handle[i].connection_type;
1108 :
1109 0 : if (connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
1110 : /* Check if log level of running application needs an update */
1111 0 : dlt_daemon_logstorage_update_application_loglevel(daemon, daemon_local, i, verbose);
1112 : }
1113 :
1114 : return DLT_RETURN_OK;
1115 : }
1116 :
1117 2 : DltReturnValue dlt_gateway_process_passive_node_messages(
1118 : DltDaemon* daemon, DltDaemonLocal* daemon_local, DltReceiver* receiver, int verbose)
1119 : {
1120 : int i = 0;
1121 : DltGateway* gateway = NULL;
1122 : DltGatewayConnection* con = NULL;
1123 2 : DltMessage msg = {0};
1124 : bool b_reset_receiver = false;
1125 :
1126 2 : if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) {
1127 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
1128 1 : return DLT_RETURN_WRONG_PARAMETER;
1129 : }
1130 :
1131 1 : PRINT_FUNCTION_VERBOSE(verbose);
1132 :
1133 : gateway = &daemon_local->pGateway;
1134 :
1135 : if (gateway == NULL) {
1136 : dlt_log(LOG_ERR, "Gateway structure is NULL\n");
1137 : return DLT_RETURN_ERROR;
1138 : }
1139 :
1140 1 : for (i = 0; i < gateway->num_connections; i++)
1141 1 : if ((gateway->connections[i].status == DLT_GATEWAY_CONNECTED)
1142 1 : && (gateway->connections[i].client.sock == receiver->fd)) {
1143 : con = &gateway->connections[i];
1144 : break;
1145 : }
1146 :
1147 1 : if (con == NULL) {
1148 0 : dlt_log(LOG_ERR, "Cannot associate fd to passive Node connection\n");
1149 0 : return DLT_RETURN_ERROR;
1150 : }
1151 :
1152 : /* now the corresponding passive node connection is available */
1153 1 : if (dlt_message_init(&msg, verbose) == -1) {
1154 0 : dlt_log(LOG_ERR, "Cannot initialize DLT message for passive node forwarding\n");
1155 0 : return DLT_RETURN_ERROR;
1156 : }
1157 :
1158 : /* nearly copy and paste of dlt_client_main_loop function */
1159 1 : if (dlt_receiver_receive(receiver) <= 0) {
1160 : /* No more data to be received */
1161 1 : if (dlt_message_free(&msg, verbose) < 0) {
1162 0 : dlt_log(LOG_ERR, "Cannot free DLT message\n");
1163 0 : return DLT_RETURN_ERROR;
1164 : }
1165 :
1166 1 : dlt_log(LOG_WARNING, "Connection to passive node lost\n");
1167 :
1168 1 : if (con->reconnect_cnt < DLT_GATEWAY_RECONNECT_MAX) {
1169 1 : dlt_log(LOG_WARNING, "Try to reconnect.\n");
1170 1 : con->reconnect_cnt += 1;
1171 1 : con->timeout_cnt = 0;
1172 : } else {
1173 0 : con->status = DLT_GATEWAY_DISCONNECTED;
1174 :
1175 0 : if (dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, receiver->fd) != 0)
1176 0 : dlt_log(LOG_ERR, "Remove passive node Connection failed\n");
1177 : }
1178 :
1179 1 : return DLT_RETURN_OK;
1180 : }
1181 :
1182 0 : while (dlt_message_read(&msg, (unsigned char*)receiver->buf, (unsigned int)receiver->bytesRcvd, 0, verbose)
1183 0 : == DLT_MESSAGE_ERROR_OK) {
1184 : DltStandardHeaderExtra* header =
1185 : (DltStandardHeaderExtra*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader));
1186 :
1187 : /* only forward messages if the received ECUid is the expected one */
1188 0 : if (strncmp(header->ecu, con->ecuid, DLT_ID_SIZE) == 0) {
1189 : uint32_t id;
1190 : uint32_t id_tmp;
1191 0 : DltPassiveControlMessage* control_msg = con->p_control_msgs;
1192 :
1193 0 : dlt_vlog(
1194 : LOG_DEBUG,
1195 : "Received ECUid (%.*s) similar to configured ECUid(%s). "
1196 : "Forwarding message (%s).\n",
1197 : DLT_ID_SIZE, header->ecu, con->ecuid, msg.databuffer);
1198 :
1199 0 : id_tmp = *((uint32_t*)(msg.databuffer));
1200 0 : id = DLT_ENDIAN_GET_32(msg.standardheader->htyp, id_tmp);
1201 :
1202 : /* if ID is GET_LOG_INFO, parse msg */
1203 0 : if (id == DLT_SERVICE_ID_GET_LOG_INFO) {
1204 0 : while (control_msg) {
1205 0 : if (control_msg->id == id) {
1206 0 : if (dlt_gateway_parse_get_log_info(daemon, header->ecu, &msg, control_msg->req, verbose)
1207 : == DLT_RETURN_ERROR)
1208 0 : dlt_log(LOG_WARNING, "Parsing GET_LOG_INFO message failed!\n");
1209 :
1210 : /* Check for logstorage */
1211 0 : dlt_gateway_control_service_logstorage(daemon, daemon_local, verbose);
1212 :
1213 : /* initialize the flag */
1214 0 : control_msg->req = CONTROL_MESSAGE_NOT_REQUESTED;
1215 0 : break;
1216 : }
1217 :
1218 0 : control_msg = control_msg->next;
1219 : }
1220 0 : } else if (id == DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL) {
1221 0 : if (dlt_gateway_parse_get_default_log_level(daemon, daemon_local, header->ecu, &msg, verbose)
1222 : == DLT_RETURN_ERROR)
1223 0 : dlt_log(LOG_WARNING, "Parsing GET_DEFAULT_LOG_LEVEL message failed!\n");
1224 : }
1225 :
1226 : /* prepare storage header */
1227 0 : if (dlt_set_storageheader(msg.storageheader, msg.headerextra.ecu) == DLT_RETURN_ERROR) {
1228 0 : dlt_vlog(LOG_ERR, "%s: Can't set storage header\n", __func__);
1229 0 : return DLT_RETURN_ERROR;
1230 : }
1231 :
1232 0 : dlt_daemon_client_send(
1233 : DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local, msg.headerbuffer, (int)sizeof(DltStorageHeader),
1234 0 : msg.headerbuffer + sizeof(DltStorageHeader), (int)((size_t)msg.headersize - sizeof(DltStorageHeader)),
1235 0 : msg.databuffer, (int)((size_t)msg.datasize), verbose);
1236 : } else { /* otherwise remove this connection and do not connect again */
1237 0 : dlt_vlog(
1238 : LOG_WARNING,
1239 : "Received ECUid (%.*s) differs to configured ECUid(%s). "
1240 : "Discard this message.\n",
1241 : DLT_ID_SIZE, header->ecu, con->ecuid);
1242 :
1243 : /* disconnect from passive node */
1244 0 : con->status = DLT_GATEWAY_DISCONNECTED;
1245 0 : con->trigger = DLT_GATEWAY_DISABLED;
1246 :
1247 0 : if (dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, receiver->fd) != 0)
1248 0 : dlt_log(LOG_ERR, "Remove passive node Connection failed\n");
1249 :
1250 0 : dlt_log(LOG_WARNING, "Disconnect from passive node due to invalid ECUid\n");
1251 :
1252 : /* it is possible that a partial log was received through the last recv call */
1253 : /* however, the rest will never be received since the socket will be closed by above method */
1254 : /* as such, we need to reset the receiver to prevent permanent corruption */
1255 : b_reset_receiver = true;
1256 : }
1257 :
1258 0 : if (msg.found_serialheader) {
1259 0 : if (dlt_receiver_remove(
1260 0 : receiver, (int)((size_t)msg.headersize + (size_t)msg.datasize - sizeof(DltStorageHeader)
1261 0 : + sizeof(dltSerialHeader)))
1262 : == -1) {
1263 : /* Return value ignored */
1264 0 : dlt_message_free(&msg, verbose);
1265 0 : return DLT_RETURN_ERROR;
1266 : }
1267 0 : } else if (
1268 0 : dlt_receiver_remove(
1269 0 : receiver, (int)((size_t)msg.headersize + (size_t)msg.datasize - sizeof(DltStorageHeader)))
1270 : == -1) {
1271 : /* Return value ignored */
1272 0 : dlt_message_free(&msg, verbose);
1273 0 : return DLT_RETURN_ERROR;
1274 : }
1275 : }
1276 :
1277 0 : if (b_reset_receiver)
1278 0 : dlt_receiver_remove(receiver, receiver->bytesRcvd);
1279 :
1280 0 : if (dlt_receiver_move_to_begin(receiver) == -1) {
1281 : /* Return value ignored */
1282 0 : dlt_message_free(&msg, verbose);
1283 0 : return DLT_RETURN_ERROR;
1284 : }
1285 :
1286 0 : if (dlt_message_free(&msg, verbose) == -1)
1287 : return DLT_RETURN_ERROR;
1288 :
1289 : return DLT_RETURN_OK;
1290 : }
1291 :
1292 2 : int dlt_gateway_process_gateway_timer(
1293 : DltDaemon* daemon, DltDaemonLocal* daemon_local, DltReceiver* receiver, int verbose)
1294 : {
1295 2 : uint64_t expir = 0;
1296 : ssize_t res = 0;
1297 :
1298 2 : PRINT_FUNCTION_VERBOSE(verbose);
1299 :
1300 2 : if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
1301 1 : dlt_vlog(LOG_ERR, "%s: invalid parameters\n", __func__);
1302 1 : return DLT_RETURN_WRONG_PARAMETER;
1303 : }
1304 :
1305 1 : res = read(receiver->fd, &expir, sizeof(expir));
1306 :
1307 1 : if (res < 0)
1308 1 : dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__, strerror(errno));
1309 : /* Activity received on timer_wd, but unable to read the fd:
1310 : * let's go on sending notification */
1311 :
1312 : /* try to connect to passive nodes */
1313 1 : dlt_gateway_establish_connections(&daemon_local->pGateway, daemon_local, verbose);
1314 :
1315 1 : dlt_log(LOG_DEBUG, "Gateway Timer\n");
1316 :
1317 1 : return DLT_RETURN_OK;
1318 : }
1319 :
1320 0 : int dlt_gateway_forward_control_message(
1321 : DltGateway* gateway, DltDaemonLocal* daemon_local, DltMessage* msg, char* ecu, int verbose)
1322 : {
1323 : int i = 0;
1324 : int ret = 0;
1325 : DltGatewayConnection* con = NULL;
1326 : uint32_t id_tmp;
1327 : uint32_t id;
1328 :
1329 0 : PRINT_FUNCTION_VERBOSE(verbose);
1330 :
1331 0 : if ((gateway == NULL) || (daemon_local == NULL) || (msg == NULL) || (ecu == NULL)) {
1332 0 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
1333 0 : return DLT_RETURN_WRONG_PARAMETER;
1334 : }
1335 :
1336 0 : for (i = 0; i < gateway->num_connections; i++)
1337 0 : if (strncmp(gateway->connections[i].ecuid, ecu, DLT_ID_SIZE) == 0) {
1338 : con = &gateway->connections[i];
1339 : break;
1340 : }
1341 :
1342 :
1343 :
1344 0 : if (con == NULL) {
1345 0 : dlt_log(LOG_WARNING, "Unknown passive node identifier\n");
1346 0 : return DLT_RETURN_ERROR;
1347 : }
1348 :
1349 0 : if (con->status != DLT_GATEWAY_CONNECTED) {
1350 0 : dlt_log(LOG_INFO, "Passive node is not connected\n");
1351 0 : return DLT_RETURN_ERROR;
1352 : }
1353 :
1354 0 : if (con->send_serial) { /* send serial header */
1355 0 : ret = (int)send(con->client.sock, (const void*)dltSerialHeader, sizeof(dltSerialHeader), 0);
1356 :
1357 0 : if (ret == -1) {
1358 0 : dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1359 0 : return DLT_RETURN_ERROR;
1360 : }
1361 : }
1362 :
1363 0 : ret = (int)send(
1364 : con->client.sock, msg->headerbuffer + sizeof(DltStorageHeader),
1365 0 : (size_t)(msg->headersize - (int)sizeof(DltStorageHeader)), 0);
1366 :
1367 0 : if (ret == -1) {
1368 0 : dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1369 0 : return DLT_RETURN_ERROR;
1370 : } else {
1371 0 : ret = (int)send(con->client.sock, msg->databuffer, (size_t)msg->datasize, 0);
1372 :
1373 0 : if (ret == -1) {
1374 0 : dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1375 0 : return DLT_RETURN_ERROR;
1376 : }
1377 : }
1378 :
1379 0 : id_tmp = *((uint32_t*)(msg->databuffer));
1380 0 : id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
1381 :
1382 0 : dlt_vlog(LOG_INFO, "Control message forwarded : %s\n", dlt_get_service_name(id));
1383 0 : return DLT_RETURN_OK;
1384 : }
1385 :
1386 0 : int dlt_gateway_forward_control_message_v2(
1387 : DltGateway* gateway, DltDaemonLocal* daemon_local, DltMessageV2* msg, uint8_t eculen, char* ecu, int verbose)
1388 : {
1389 : int i = 0;
1390 : int ret = 0;
1391 : DltGatewayConnection* con = NULL;
1392 : uint32_t id_tmp;
1393 : uint32_t id;
1394 :
1395 0 : PRINT_FUNCTION_VERBOSE(verbose);
1396 :
1397 0 : if ((gateway == NULL) || (daemon_local == NULL) || (msg == NULL) || (ecu == NULL)) {
1398 0 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
1399 0 : return DLT_RETURN_WRONG_PARAMETER;
1400 : }
1401 :
1402 0 : for (i = 0; i < gateway->num_connections; i++)
1403 0 : if (strncmp(gateway->connections[i].ecuid2, ecu, eculen) == 0) {
1404 : con = &gateway->connections[i];
1405 : break;
1406 : }
1407 :
1408 :
1409 :
1410 0 : if (con == NULL) {
1411 0 : dlt_log(LOG_WARNING, "Unknown passive node identifier\n");
1412 0 : return DLT_RETURN_ERROR;
1413 : }
1414 :
1415 0 : if (con->status != DLT_GATEWAY_CONNECTED) {
1416 0 : dlt_log(LOG_INFO, "Passive node is not connected\n");
1417 0 : return DLT_RETURN_ERROR;
1418 : }
1419 :
1420 0 : if (con->send_serial) { /* send serial header */
1421 0 : ret = (int)send(con->client.sock, (const void*)dltSerialHeader, sizeof(dltSerialHeader), 0);
1422 :
1423 0 : if (ret == -1) {
1424 0 : dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1425 0 : return DLT_RETURN_ERROR;
1426 : }
1427 : }
1428 :
1429 : // TBD: Review if storage header needs to be sent for v2
1430 : // TBD: Review msg->storageheadersizev2 or need to calculate size
1431 0 : ret = (int)send(
1432 0 : con->client.sock, (const void*)(msg->headerbufferv2 + msg->storageheadersizev2),
1433 0 : (size_t)(msg->headersizev2 - (int32_t)msg->storageheadersizev2), 0);
1434 :
1435 0 : if (ret == -1) {
1436 0 : dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1437 0 : return DLT_RETURN_ERROR;
1438 : } else {
1439 0 : ret = (int)send(con->client.sock, msg->databuffer, (size_t)msg->datasize, 0);
1440 :
1441 0 : if (ret == -1) {
1442 0 : dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1443 0 : return DLT_RETURN_ERROR;
1444 : }
1445 : }
1446 :
1447 0 : id_tmp = *((uint32_t*)(msg->databuffer));
1448 : // TBD: Review id extraction for v2
1449 0 : id = DLT_ENDIAN_GET_32(msg->baseheaderv2->htyp2, id_tmp);
1450 :
1451 : // TBD: Review check if dlt_get_service_name_v2 is needed
1452 0 : dlt_vlog(LOG_INFO, "Control message forwarded : %s\n", dlt_get_service_name(id));
1453 0 : return DLT_RETURN_OK;
1454 : }
1455 :
1456 3 : DltReturnValue dlt_gateway_process_on_demand_request(
1457 : DltGateway* gateway, DltDaemonLocal* daemon_local, char* node_id, int conn_status, int verbose)
1458 : {
1459 : int i = 0;
1460 : DltGatewayConnection* con = NULL;
1461 :
1462 3 : PRINT_FUNCTION_VERBOSE(verbose);
1463 :
1464 3 : if ((gateway == NULL) || (daemon_local == NULL) || (node_id == NULL)) {
1465 1 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
1466 1 : return DLT_RETURN_WRONG_PARAMETER;
1467 : }
1468 :
1469 : /* find connection by ECU id */
1470 2 : for (i = 0; i < gateway->num_connections; i++) {
1471 2 : if (strncmp(node_id, gateway->connections[i].ecuid, DLT_ID_SIZE) == 0) {
1472 : con = &gateway->connections[i];
1473 : break;
1474 : }
1475 : }
1476 :
1477 2 : if (con == NULL) {
1478 0 : dlt_log(LOG_WARNING, "Specified ECUid not found\n");
1479 0 : return DLT_RETURN_ERROR;
1480 : }
1481 :
1482 2 : if (conn_status == 1) { /* try to connect */
1483 :
1484 2 : if (con->status != DLT_GATEWAY_CONNECTED) {
1485 1 : if (dlt_client_connect(&con->client, verbose) == 0) {
1486 : /* setup dlt connection and add to poll event loop here */
1487 0 : if (dlt_gateway_add_to_event_loop(daemon_local, con, verbose) != DLT_RETURN_OK) {
1488 0 : dlt_log(LOG_ERR, "Gateway connection creation failed\n");
1489 0 : return DLT_RETURN_ERROR;
1490 : }
1491 : } else {
1492 1 : dlt_log(LOG_ERR, "Could not connect to passive node\n");
1493 1 : return DLT_RETURN_ERROR;
1494 : }
1495 : } else {
1496 1 : dlt_log(LOG_INFO, "Passive node already connected\n");
1497 : }
1498 0 : } else if (conn_status == 0) /* disconnect*/
1499 : {
1500 0 : con->status = DLT_GATEWAY_DISCONNECTED;
1501 0 : con->trigger = DLT_GATEWAY_ON_DEMAND;
1502 :
1503 0 : if (dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, con->client.sock) != 0)
1504 0 : dlt_log(LOG_ERR, "Remove passive node event handler connection failed\n");
1505 : } else {
1506 0 : dlt_log(LOG_ERR, "Unknown command (connection_status)\n");
1507 0 : return DLT_RETURN_ERROR;
1508 : }
1509 :
1510 : return DLT_RETURN_OK;
1511 : }
1512 :
1513 10 : int dlt_gateway_send_control_message(
1514 : DltGatewayConnection* con, DltPassiveControlMessage* control_msg, void* data, int verbose)
1515 : {
1516 : int ret = DLT_RETURN_OK;
1517 :
1518 10 : PRINT_FUNCTION_VERBOSE(verbose);
1519 :
1520 10 : if (con == NULL) {
1521 1 : dlt_vlog(LOG_WARNING, "%s: Invalid parameter given\n", __func__);
1522 1 : return DLT_RETURN_WRONG_PARAMETER;
1523 : }
1524 :
1525 : /* no (more) control message to be send */
1526 9 : if (control_msg->id == 0)
1527 : return DLT_RETURN_ERROR;
1528 :
1529 : /* check sendtime counter and message interval */
1530 : /* sendtime counter is 0 on startup, otherwise positive value */
1531 9 : if ((control_msg->type != CONTROL_MESSAGE_ON_DEMAND) && (con->sendtime_cnt > 0)) {
1532 0 : if ((control_msg->interval) == 0)
1533 : return DLT_RETURN_ERROR;
1534 :
1535 0 : if ((control_msg->type == CONTROL_MESSAGE_PERIODIC) || (control_msg->type == CONTROL_MESSAGE_BOTH)) {
1536 0 : if ((con->sendtime_cnt - 1) % control_msg->interval != 0)
1537 : return DLT_RETURN_ERROR;
1538 : }
1539 : }
1540 :
1541 9 : if (con->send_serial) { /* send serial header */
1542 0 : ret = (int)send(con->client.sock, (const void*)dltSerialHeader, sizeof(dltSerialHeader), 0);
1543 :
1544 0 : if (ret == -1) {
1545 0 : dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1546 0 : return DLT_RETURN_ERROR;
1547 : }
1548 : }
1549 :
1550 9 : switch (control_msg->id) {
1551 3 : case DLT_SERVICE_ID_GET_LOG_INFO:
1552 3 : return dlt_client_get_log_info(&con->client);
1553 : break;
1554 1 : case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
1555 1 : return dlt_client_get_default_log_level(&con->client);
1556 : break;
1557 3 : case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
1558 3 : return dlt_client_get_software_version(&con->client);
1559 : break;
1560 2 : case DLT_SERVICE_ID_SET_LOG_LEVEL:
1561 :
1562 2 : if (data == NULL) {
1563 1 : dlt_vlog(
1564 : LOG_WARNING, "Insufficient data for %s received. Send control request failed.\n",
1565 : dlt_get_service_name(control_msg->id));
1566 1 : return DLT_RETURN_ERROR;
1567 : }
1568 :
1569 : DltServiceSetLogLevel* req = (DltServiceSetLogLevel*)data;
1570 1 : return dlt_client_send_log_level(&con->client, req->apid, req->ctid, req->log_level);
1571 : break;
1572 0 : default:
1573 0 : dlt_vlog(LOG_WARNING, "Cannot forward request: %s.\n", dlt_get_service_name(control_msg->id));
1574 : }
1575 :
1576 0 : return DLT_RETURN_OK;
1577 : }
1578 :
1579 0 : int dlt_gateway_send_control_message_v2(
1580 : DltGatewayConnection* con, DltPassiveControlMessage* control_msg, void* data, int verbose)
1581 : {
1582 : int ret = DLT_RETURN_OK;
1583 :
1584 0 : PRINT_FUNCTION_VERBOSE(verbose);
1585 :
1586 0 : if (con == NULL) {
1587 0 : dlt_vlog(LOG_WARNING, "%s: Invalid parameter given\n", __func__);
1588 0 : return DLT_RETURN_WRONG_PARAMETER;
1589 : }
1590 :
1591 : /* no (more) control message to be send */
1592 0 : if (control_msg->id == 0)
1593 : return DLT_RETURN_ERROR;
1594 :
1595 : /* check sendtime counter and message interval */
1596 : /* sendtime counter is 0 on startup, otherwise positive value */
1597 0 : if ((control_msg->type != CONTROL_MESSAGE_ON_DEMAND) && (con->sendtime_cnt > 0)) {
1598 0 : if (control_msg->interval == 0)
1599 : return DLT_RETURN_ERROR;
1600 :
1601 0 : if ((control_msg->type == CONTROL_MESSAGE_PERIODIC) || (control_msg->type == CONTROL_MESSAGE_BOTH)) {
1602 0 : if ((con->sendtime_cnt - 1) % control_msg->interval != 0)
1603 : return DLT_RETURN_ERROR;
1604 : }
1605 : }
1606 :
1607 0 : if (con->send_serial) { /* send serial header */
1608 0 : ret = (int)send(con->client.sock, (const void*)dltSerialHeader, sizeof(dltSerialHeader), 0);
1609 :
1610 0 : if (ret == -1) {
1611 0 : dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1612 0 : return DLT_RETURN_ERROR;
1613 : }
1614 : }
1615 :
1616 0 : switch (control_msg->id) {
1617 0 : case DLT_SERVICE_ID_GET_LOG_INFO:
1618 0 : return dlt_client_get_log_info_v2(&con->client);
1619 : break;
1620 0 : case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
1621 0 : return dlt_client_get_default_log_level_v2(&con->client);
1622 : break;
1623 0 : case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
1624 0 : return dlt_client_get_software_version_v2(&con->client);
1625 : break;
1626 0 : case DLT_SERVICE_ID_SET_LOG_LEVEL:
1627 :
1628 0 : if (data == NULL) {
1629 0 : dlt_vlog(
1630 : LOG_WARNING, "Insufficient data for %s received. Send control request failed.\n",
1631 : dlt_get_service_name(control_msg->id));
1632 0 : return DLT_RETURN_ERROR;
1633 : }
1634 :
1635 : DltServiceSetLogLevel* req = (DltServiceSetLogLevel*)data;
1636 0 : return dlt_client_send_log_level_v2(&con->client, req->apid, req->ctid, req->log_level);
1637 : break;
1638 0 : default:
1639 0 : dlt_vlog(LOG_WARNING, "Cannot forward request: %s.\n", dlt_get_service_name(control_msg->id));
1640 : }
1641 :
1642 0 : return DLT_RETURN_OK;
1643 : }
1644 :
1645 0 : DltGatewayConnection* dlt_gateway_get_connection(DltGateway* gateway, char* ecu, int verbose)
1646 : {
1647 : DltGatewayConnection* con = NULL;
1648 : int i = 0;
1649 :
1650 0 : PRINT_FUNCTION_VERBOSE(verbose);
1651 :
1652 0 : if ((gateway == NULL) || (ecu == NULL)) {
1653 0 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
1654 0 : return con;
1655 : }
1656 :
1657 0 : for (i = 0; i < gateway->num_connections; i++) {
1658 0 : con = &gateway->connections[i];
1659 :
1660 0 : if (strncmp(con->ecuid, ecu, DLT_ID_SIZE) == 0)
1661 0 : return con;
1662 : }
1663 :
1664 0 : dlt_vlog(LOG_ERR, "%s: No connection found\n", ecu);
1665 :
1666 0 : return con;
1667 : }
1668 :
1669 0 : DltGatewayConnection* dlt_gateway_get_connection_v2(DltGateway* gateway, char* ecu, int verbose)
1670 : {
1671 : DltGatewayConnection* con = NULL;
1672 : int i = 0;
1673 :
1674 0 : PRINT_FUNCTION_VERBOSE(verbose);
1675 :
1676 0 : if ((gateway == NULL) || (ecu == NULL)) {
1677 0 : dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
1678 0 : return con;
1679 : }
1680 :
1681 0 : for (i = 0; i < gateway->num_connections; i++) {
1682 0 : con = &gateway->connections[i];
1683 : // TBD: REVIEW strlen(ecu) usage
1684 0 : if (strncmp(con->ecuid2, ecu, strlen(ecu)) == 0)
1685 0 : return con;
1686 : }
1687 :
1688 0 : dlt_vlog(LOG_ERR, "%s: No connection found\n", ecu);
1689 :
1690 0 : return con;
1691 : }
|