automotive-dlt
dlt_gateway.c
Go to the documentation of this file.
1 /*
2  * @licence app begin@
3  * SPDX license identifier: MPL-2.0
4  *
5  * Copyright (C) 2015 Advanced Driver Information Technology.
6  * This code is developed by Advanced Driver Information Technology.
7  * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
8  *
9  * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
10  *
11  * This Source Code Form is subject to the terms of the
12  * Mozilla Public License (MPL), v. 2.0.
13  * If a copy of the MPL was not distributed with this file,
14  * You can obtain one at http://mozilla.org/MPL/2.0/.
15  *
16  * For further information see http://www.genivi.org/.
17  * @licence end@
18  */
19 
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <syslog.h>
34 #include <arpa/inet.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <netdb.h>
38 #include <limits.h>
39 #include <errno.h>
40 #include "dlt_gateway.h"
41 #include "dlt_config_file_parser.h"
42 #include "dlt_common.h"
43 #include "dlt-daemon_cfg.h"
45 #include "dlt_daemon_connection.h"
46 #include "dlt_daemon_client.h"
47 
48 typedef struct {
49  char *key; /* The configuration key*/
50  int (*func)(DltGatewayConnection *con, char *value); /* Conf handler */
51  int is_opt; /* If the configuration is optional or not */
53 #ifndef DLT_UNIT_TESTS
54 typedef enum {
64 #endif
65 
73 {
74  struct sockaddr_in sa;
75  int ret = -1;
76 
77  if (con == NULL || value == NULL)
78  {
79  return -1;
80  }
81 
82  ret = inet_pton(AF_INET, value, &(sa.sin_addr));
83 
84  /* valid IP address */
85  if (ret != 0)
86  {
87  con->ip_address = strdup(value);
88 
89  if (con->ip_address == NULL)
90  {
91  dlt_log(LOG_ERR, "Cannot copy passive node IP address string\n");
92  return -1;
93  }
94 
95  return 0;
96  }
97  else
98  {
99  dlt_log(LOG_ERR, "IP address is not valid\n");
100  }
101 
102  return -1;
103 }
104 
113 {
114  int tmp = -1;
115 
116  if (con == NULL || value == NULL)
117  {
118  return -1;
119  }
120 
121  tmp = (int) strtol(value, NULL, 10);
122 
123  /* port ranges for unprivileged applications */
124  if (tmp > IPPORT_RESERVED && tmp <= USHRT_MAX)
125  {
126  con->port = tmp;
127  return 0;
128  }
129  else
130  {
131  dlt_log(LOG_ERR, "Port number is invalid\n");
132  }
133 
134  return -1;
135 }
136 
145 {
146  if (con == NULL || value == NULL)
147  {
148  return -1;
149  }
150 
151  con->ecuid = strdup(value);
152 
153  if (con->ecuid == NULL)
154  {
155  return -1;
156  }
157 
158  return 0;
159 }
160 
169  char *value)
170 {
171  if (con == NULL || value == NULL)
172  {
173  return -1;
174  }
175 
176  if (strncasecmp(value, "OnStartup", strlen("OnStartup")) == 0)
177  {
179  }
180  else if (strncasecmp(value, "OnDemand", strlen("OnDemand")) == 0)
181  {
183  }
184  else
185  {
186  dlt_log(LOG_ERR, "Wrong connection trigger state given.\n");
188  return -1;
189  }
190 
191  return 0;
192 }
193 
202 {
203  if (con == NULL || value == NULL)
204  {
205  return -1;
206  }
207 
208  con->timeout = (int) strtol(value, NULL, 10);
209 
210  if (con->timeout > 0)
211  {
212  return 0;
213  }
214 
215  return -1;
216 }
217 
226 {
227  if (con == NULL || value == NULL)
228  {
229  return -1;
230  }
231 
232  con->send_serial = !!((int) strtol(value, NULL, 10));
233 
234  return 0;
235 }
236 
245  char *value)
246 {
247  /* list of allowed clients given */
248  char *token = NULL;
249  char *rest = NULL;
250  int i = 0;
251  char error_msg[DLT_DAEMON_TEXTBUFSIZE];
252 
253  if (con == NULL || value == NULL)
254  {
255  return -1;
256  }
257 
258  if (strlen(value) == 0)
259  {
260  memset(con->control_msgs,
261  0,
262  sizeof(int) * DLT_GATEWAY_MAX_STARTUP_CTRL_MSG);
263  return 0;
264  }
265 
266  token = strtok_r(value, ",", &rest);
267  while (token != NULL && i < DLT_GATEWAY_MAX_STARTUP_CTRL_MSG)
268  {
269 
270  con->control_msgs[i] = strtol(token, NULL, 16);
271 
272  if (errno == EINVAL || errno == ERANGE)
273  {
274  snprintf(error_msg,
276  "Control message ID is not an integer: %s\n", token);
277  dlt_log(LOG_ERR, error_msg);
278  return -1;
279  }
280  else if (con->control_msgs[i] < DLT_SERVICE_ID_SET_LOG_LEVEL ||
282  {
283  snprintf(error_msg,
285  "Control message ID is not valid: %s\n", token);
286  dlt_log(LOG_ERR, error_msg);
287  return -1;
288  }
289 
290  token = strtok_r(NULL, ",", &rest);
291  i++;
292  }
293 
294  return 0;
295 }
296 
303 {
304  [GW_CONF_IP_ADDRESS] = {
305  .key = "IPaddress",
306  .func = dlt_gateway_check_ip,
307  .is_opt = 0 },
308  [GW_CONF_PORT] = {
309  .key = "Port",
310  .func = dlt_gateway_check_port,
311  .is_opt = 1 },
312  [GW_CONF_ECUID] = {
313  .key = "EcuID",
314  .func = dlt_gateway_check_ecu,
315  .is_opt = 0 },
316  [GW_CONF_CONNECT] = {
317  .key = "Connect",
319  .is_opt = 1 },
320  [GW_CONF_TIMEOUT] = {
321  .key = "Timeout",
323  .is_opt = 0 },
325  .key = "SendControl",
327  .is_opt = 1 },
329  .key = "SendSerialHeader",
331  .is_opt = 1 }
332 };
333 
334 #define DLT_GATEWAY_NUM_PROPERTIES_MAX GW_CONF_COUNT
335 
347  DltGatewayConfType ctype,
348  char *value)
349 {
350  if (gateway == NULL || con == NULL || value == NULL)
351  {
352  return -1;
353  }
354 
355  if (ctype < GW_CONF_COUNT)
356  return configuration_entries[ctype].func(con, value);
357 
358  return -1;
359 }
360 
371  int verbose)
372 {
373  int i = 0;
374  int ret = 0;
375 
376  PRINT_FUNCTION_VERBOSE(verbose);
377 
378  if (gateway == NULL || tmp == NULL)
379  {
380  return -1;
381  }
382 
383  /* find next free entry in connection array */
384  while (i < gateway->num_connections)
385  {
386  if (gateway->connections[i].status == DLT_GATEWAY_UNINITIALIZED)
387  {
388  break;
389  }
390 
391  i++;
392  }
393 
394  if (&gateway->connections[i] == NULL)
395  {
396  return -1;
397  }
398 
399  /* store values */
400  gateway->connections[i].ip_address = strdup(tmp->ip_address);
401  gateway->connections[i].ecuid = strdup(tmp->ecuid);
402  gateway->connections[i].sock_domain = tmp->sock_domain;
403  gateway->connections[i].sock_type = tmp->sock_type;
404  gateway->connections[i].sock_protocol = tmp->sock_protocol;
405  gateway->connections[i].port = tmp->port;
406  gateway->connections[i].trigger = tmp->trigger;
407  gateway->connections[i].timeout = tmp->timeout;
408  gateway->connections[i].handle = 0;
410  memcpy(gateway->connections[i].control_msgs,
411  tmp->control_msgs,
412  sizeof(tmp->control_msgs));
413  gateway->connections[i].send_serial = tmp->send_serial;
414 
415  if (dlt_client_init_port(&gateway->connections[i].client,
416  gateway->connections[i].port,
417  verbose) != 0)
418  {
419  free(gateway->connections[i].ip_address);
420  free(gateway->connections[i].ecuid);
421  dlt_log(LOG_CRIT, "dlt_client_init() failed for gateway connection\n");
422  return -1;
423  }
425  gateway->connections[i].client.sock,
427  /* setup DltClient Structure */
429  gateway->connections[i].ip_address) == -1)
430  {
431  dlt_log(LOG_ERR,
432  "dlt_client_set_server_ip() failed for gateway connection \n");
433  return -1;
434  }
435 
436  if (ret != 0)
437  {
438  free(gateway->connections[i].ip_address);
439  free(gateway->connections[i].ecuid);
440  dlt_log(LOG_ERR, "Gateway: DltClient initialization failed\n");
441  return -1;
442  }
443 
444  return 0;
445 }
446 
455 int dlt_gateway_configure(DltGateway *gateway, char *config_file, int verbose)
456 {
457  int ret = 0;
458  int i = 0;
459  DltConfigFile *file = NULL;
460 
461  PRINT_FUNCTION_VERBOSE(verbose);
462 
463  if (gateway == NULL || config_file == 0 || config_file[0] == '\0')
464  {
465  return -1;
466  }
467 
468  /* read configuration file */
469  file = dlt_config_file_init(config_file);
470 
471  /* get number of entries and allocate memory to store information */
472  ret = dlt_config_file_get_num_sections(file, &gateway->num_connections);
473 
474  if (ret != 0)
475  {
477  dlt_log(LOG_ERR, "Invalid number of sections in configuration file\n");
478  return -1;
479  }
480 
481  gateway->connections = calloc(sizeof(DltGatewayConnection),
482  gateway->num_connections);
483 
484  if (gateway->connections == NULL)
485  {
487  dlt_log(LOG_CRIT, "Memory allocation for gateway connections failed\n");
488  return -1;
489  }
490 
491  for (i = 0; i < gateway->num_connections; i++)
492  {
493  char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' };
495  int invalid = 0;
496  DltGatewayConfType j = 0;
497  char section[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = {'\0'};
498  char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = {'\0'};
499 
500  memset(&tmp, 0, sizeof(tmp));
501 
502  /* Set default */
503  tmp.send_serial = gateway->send_serial;
505 
506  ret = dlt_config_file_get_section_name(file, i, section);
507 
508  for (j = 0; j < GW_CONF_COUNT; j++)
509  {
510  ret = dlt_config_file_get_value(file,
511  section,
512  configuration_entries[j].key,
513  value);
514 
515  if ((ret != 0) && configuration_entries[j].is_opt)
516  {
517  /* Use default values for this key */
518  snprintf(local_str,
520  "Using default for %s.\n",
521  configuration_entries[j].key);
522  dlt_log(LOG_WARNING, local_str);
523  continue;
524  }
525  else if (ret != 0)
526  {
527  snprintf(local_str,
529  "Missing configuration for %s.\n",
530  configuration_entries[j].key);
531  dlt_log(LOG_WARNING, local_str);
532  invalid = 1;
533  break;
534  }
535 
536  /* check value and store temporary */
537  ret = dlt_gateway_check_param(gateway, &tmp, j, value);
538 
539  if (ret != 0)
540  {
541  sprintf(local_str,
542  "Configuration %s = %s is invalid.\n"
543  "Using default.\n",
544  configuration_entries[j].key, value);
545  dlt_log(LOG_ERR, local_str);
546  }
547  }
548 
549  if (invalid)
550  {
551  memset(local_str, 0, DLT_DAEMON_TEXTBUFSIZE);
552  sprintf(local_str,
553  "%s configuration is invalid.\n"
554  "Ignoring.\n",
555  section);
556  dlt_log(LOG_ERR, local_str);
557  }
558  else
559  {
560  ret = dlt_gateway_store_connection(gateway, &tmp, verbose);
561 
562  if (ret != 0)
563  {
564  dlt_log(LOG_ERR, "Storing gateway connection data failed\n");
565  }
566  }
567 
568  /* strdup used inside some get_value function */
569  free(tmp.ecuid);
570  free(tmp.ip_address);
571  }
572 
574  return ret;
575 }
576 
577 int dlt_gateway_init(DltDaemonLocal *daemon_local, int verbose)
578 {
579  PRINT_FUNCTION_VERBOSE(verbose);
580 
581  if (daemon_local == NULL)
582  {
583  return -1;
584  }
585 
586  DltGateway *gateway = &daemon_local->pGateway;
587 
588  if (gateway != NULL)
589  {
590  /* Get default value from daemon_local */
591  gateway->send_serial = daemon_local->flags.lflag;
592 
593  if (dlt_gateway_configure(gateway,
594  daemon_local->flags.gatewayConfigFile,
595  verbose) != 0)
596  {
597  dlt_log(LOG_ERR, "Gateway initialization failed\n");
598  return -1;
599  }
600  }
601  else
602  {
603  dlt_log(LOG_CRIT, "Pointer to Gateway structure is NULL\n");
604  return -1;
605  }
606 
607  /* ignore return value */
608  dlt_gateway_establish_connections(gateway, daemon_local, verbose);
609 
610  return 0;
611 }
612 
613 void dlt_gateway_deinit(DltGateway *gateway, int verbose)
614 {
615  int i = 0;
616 
617  if (gateway == NULL)
618  {
619  return;
620  }
621 
622  PRINT_FUNCTION_VERBOSE(verbose);
623 
624  for (i = 0; i < gateway->num_connections; i++)
625  {
626  DltGatewayConnection *c = &gateway->connections[i];
627  dlt_client_cleanup(&c->client, verbose);
628  free(c->ip_address);
629  free(c->ecuid);
630  }
631 
632  free(gateway->connections);
633  free(gateway);
634 }
635 
637  DltDaemonLocal *daemon_local,
638  int verbose)
639 {
640  int i = 0;
641  int ret = 0;
642 
643  PRINT_FUNCTION_VERBOSE(verbose);
644 
645  if (gateway == NULL || daemon_local == NULL)
646  {
647  return -1;
648  }
649 
650  for (i = 0; i < gateway->num_connections; i++)
651  {
652  DltGatewayConnection *con = &(gateway->connections[i]);
653  if (con == NULL)
654  {
655  dlt_log(LOG_CRIT, "Cannot retrieve gateway connection details\n");
656  return -1;
657  }
658 
659  if (con->status != DLT_GATEWAY_CONNECTED &&
660  con->trigger != DLT_GATEWAY_ON_DEMAND &&
662  {
663  ret = dlt_client_connect(&con->client, verbose);
664 
665  if (ret == 0)
666  {
667  /* connection to passive node established, add to event loop */
669  con->reconnect_cnt = 0;
670  con->timeout_cnt = 0;
671 
672  /* setup dlt connection and add to epoll event loop here */
673  if (dlt_connection_create(daemon_local,
674  &daemon_local->pEvent,
675  con->client.sock,
676  EPOLLIN,
678  {
679  dlt_log(LOG_ERR, "Gateway connection creation failed\n");
680  return -1;
681  }
682 
683  /* immediately send configured control messages */
685  gateway,
686  daemon_local,
687  verbose);
688 
689  }
690  else
691  {
692  dlt_log(LOG_DEBUG,
693  "Passive Node is not up. Connection failed.\n");
694 
695  con->timeout_cnt++;
696  if (con->timeout_cnt > con->timeout)
697  {
699  dlt_log(LOG_WARNING,
700  "Passive Node connection retry timed out. "
701  "Give up.\n");
702  }
703  }
704  }
705  }
706 
707  return 0;
708 }
709 
711 {
712  int i = 0;
713 
714  if (gateway == NULL)
715  {
716  return NULL;
717  }
718 
719  for (i = 0; i < gateway->num_connections; i++)
720  {
721  DltGatewayConnection *c = &gateway->connections[i];
722  if (c->status == DLT_GATEWAY_CONNECTED && c->client.sock == fd)
723  {
724  return &c->client.receiver;
725  }
726  }
727 
728  return NULL;
729 }
730 
732  DltDaemonLocal *daemon_local,
733  DltReceiver *receiver,
734  int verbose)
735 {
736  int i = 0;
737  DltGateway *gateway = NULL;
738  DltGatewayConnection *con = NULL;
739  DltMessage msg;
740  char local_str[DLT_DAEMON_TEXTBUFSIZE];
741 
742  if (daemon == NULL || daemon_local == NULL || receiver == NULL)
743  {
744  return -1;
745  }
746 
747  PRINT_FUNCTION_VERBOSE(verbose);
748 
749  gateway = &daemon_local->pGateway;
750  if (gateway == NULL)
751  {
752  dlt_log(LOG_ERR, "Gateway structure is NULL\n");
753  return -1;
754  }
755 
756  for (i = 0; i < gateway->num_connections; i++)
757  {
758  if (gateway->connections[i].client.sock == receiver->fd)
759  {
760  con = &gateway->connections[i];
761  break;
762  }
763  }
764 
765  if (con == NULL)
766  {
767  dlt_log(LOG_ERR, "Cannot associate fd to passive Node connection\n");
768  return -1;
769  }
770 
771  /* now the corresponding passive node connection is available */
772  if (dlt_message_init(&msg, verbose) == -1)
773  {
774  dlt_log(LOG_ERR,
775  "Cannot initialize DLT message for passive node forwarding\n");
776  return -1;
777  }
778 
779  /* nearly copy and paste of dlt_client_main_loop function */
780  if (dlt_receiver_receive_socket(receiver) <= 0)
781  {
782  /* No more data to be received */
783  if (dlt_message_free(&msg, verbose) < 0)
784  {
785  dlt_log(LOG_ERR, "Cannot free DLT message\n");
786  return -1;
787  }
788 
789  dlt_log(LOG_WARNING, "Connection to passive node lost\n");
790 
792  {
793  dlt_log(LOG_WARNING, "Try to reconnect.\n");
794  con->reconnect_cnt += 1;
795  con->timeout_cnt = 0;
796  }
797  else
798  {
801  daemon_local,
802  receiver->fd) != 0)
803  {
804  dlt_log(LOG_ERR, "Remove passive node Connection failed\n");
805  }
806  }
807  return 0;
808  }
809 
810  while (dlt_message_read(&msg,
811  (unsigned char *)receiver->buf,
812  receiver->bytesRcvd,
813  0,
814  verbose) == DLT_MESSAGE_ERROR_OK)
815  {
816  DltStandardHeaderExtra *header = (DltStandardHeaderExtra *)
817  (msg.headerbuffer +
818  sizeof(DltStorageHeader) +
819  sizeof(DltStandardHeader));
820 
821  /* only forward messages if the received ECUid is the expected one */
822  if (strncmp(header->ecu, con->ecuid, strlen(con->ecuid)) == 0)
823  {
824  snprintf(local_str,
826  "Received ECUid (%s) similar to configured ECUid(%s). "
827  "Forwarding message (%s).\n",
828  header->ecu,
829  con->ecuid,
830  msg.databuffer);
831  dlt_log(LOG_DEBUG, local_str);
832 
834  daemon,
835  daemon_local,
836  msg.headerbuffer,
837  sizeof(DltStorageHeader),
838  msg.headerbuffer + sizeof(DltStorageHeader),
839  msg.headersize - sizeof(DltStorageHeader),
840  msg.databuffer,
841  msg.datasize,
842  verbose) != DLT_DAEMON_ERROR_OK)
843  {
844  dlt_log(LOG_WARNING, "Forward message to clients failed!\n");
845  }
846  }
847  else /* otherwise remove this connection and do not connect again */
848  {
849  snprintf(local_str,
851  "Received ECUid (%s) differs to configured ECUid(%s). "
852  "Discard this message.\n",
853  header->ecu,
854  con->ecuid);
855  dlt_log(LOG_WARNING, local_str);
856 
857  /* disconnect from passive node */
861  daemon_local,
862  receiver->fd)
863  != 0)
864  {
865  dlt_log(LOG_ERR, "Remove passive node Connection failed\n");
866  }
867 
868  dlt_log(LOG_WARNING,
869  "Disconnect from passive node due to invalid ECUid\n");
870  }
871 
872  if (msg.found_serialheader)
873  {
874  if (dlt_receiver_remove(receiver,
875  msg.headersize +
876  msg.datasize -
877  sizeof(DltStorageHeader) +
878  sizeof(dltSerialHeader)) == -1)
879  {
880  /* Return value ignored */
881  dlt_message_free(&msg,verbose);
882  return -1;
883  }
884  }
885  else
886  {
887  if (dlt_receiver_remove(receiver,
888  msg.headersize +
889  msg.datasize -
890  sizeof(DltStorageHeader)) == -1)
891  {
892  /* Return value ignored */
893  dlt_message_free(&msg,verbose);
894  return -1;
895  }
896  }
897  }
898 
899  if (dlt_receiver_move_to_begin(receiver) == -1)
900  {
901  /* Return value ignored */
902  dlt_message_free(&msg, verbose);
903  return -1;
904  }
905 
906  if (dlt_message_free(&msg, verbose) == -1)
907  {
908  return -1;
909  }
910 
911  return 0;
912 }
913 
915  DltDaemonLocal *daemon_local,
916  DltReceiver *receiver,
917  int verbose)
918 {
919  uint64_t expir = 0;
920  ssize_t res = 0;
921  char local_str[DLT_DAEMON_TEXTBUFSIZE];
922 
923  PRINT_FUNCTION_VERBOSE(verbose);
924 
925  if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL))
926  {
927  snprintf(local_str,
929  "%s: invalid parameters",
930  __func__);
931  dlt_log(LOG_ERR, local_str);
932  return -1;
933  }
934 
935  res = read(receiver->fd, &expir, sizeof(expir));
936 
937  if(res < 0)
938  {
939  snprintf(local_str,
941  "%s: Fail to read timer (%s)\n", __func__, strerror(errno));
942  dlt_log(LOG_WARNING, local_str);
943  /* Activity received on timer_wd, but unable to read the fd:
944  let's go on sending notification */
945  }
946 
947  /* try to connect to passive nodes */
949  daemon_local,
950  verbose);
951 
952  dlt_log(LOG_DEBUG, "Gateway Timer\n");
953 
954  return 0;
955 }
956 
958  DltDaemonLocal *daemon_local,
959  DltMessage *msg,
960  char *ecu,
961  int verbose)
962 {
963  int i = 0;
964  int ret = 0;
965  DltGatewayConnection *con = NULL;
966 
967  PRINT_FUNCTION_VERBOSE(verbose);
968 
969  if (gateway == NULL || daemon_local == NULL || msg == NULL || ecu == NULL)
970  {
971  return -1;
972  }
973 
974  for (i = 0; i < gateway->num_connections; i++)
975  {
976  if (strncmp(gateway->connections[i].ecuid,
977  ecu,
978  strlen(gateway->connections[i].ecuid)) == 0)
979  {
980  con = &gateway->connections[i];
981  break;
982  }
983  }
984 
985  if (con == NULL)
986  {
987  dlt_log(LOG_WARNING, "Unknown passive node identifier\n");
988  return -1;
989  }
990 
991  if (con->status != DLT_GATEWAY_CONNECTED)
992  {
993  dlt_log(LOG_INFO, "Passive node is not connected\n");
994  return -1;
995  }
996 
997  if (con->send_serial) /* send serial header */
998  {
999  ret = send(con->client.sock,
1000  (void *)dltSerialHeader,
1001  sizeof(dltSerialHeader),
1002  0);
1003 
1004  if (ret == -1)
1005  {
1006  dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1007  return -1;
1008  }
1009  }
1010 
1011  ret = send(con->client.sock,
1012  msg->headerbuffer + sizeof(DltStorageHeader),
1013  msg->headersize - sizeof(DltStorageHeader),
1014  0);
1015  if (ret == -1)
1016  {
1017  dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1018  return -1;
1019  }
1020  else
1021  {
1022  ret = send(con->client.sock, msg->databuffer, msg->datasize, 0);
1023  if (ret == -1)
1024  {
1025  dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
1026  return -1;
1027  }
1028  }
1029 
1030  dlt_log(LOG_INFO, "Control message forwarded\n");
1031  return 0;
1032 }
1033 
1035  DltDaemonLocal *daemon_local,
1036  char *node_id,
1037  int connection_status,
1038  int verbose)
1039 {
1040  int i = 0;
1041  DltGatewayConnection *con = NULL;
1042 
1043  PRINT_FUNCTION_VERBOSE(verbose);
1044 
1045  if (gateway == NULL || daemon_local == NULL || node_id == NULL)
1046  {
1047  return -1;
1048  }
1049 
1050  /* find connection by ECU id */
1051  for (i = 0; i < gateway->num_connections; i++)
1052  {
1053  if (strncmp(node_id, gateway->connections->ecuid, DLT_ID_SIZE) == 0)
1054  {
1055  con = &gateway->connections[i];
1056  break;
1057  }
1058  }
1059 
1060  if (con == NULL)
1061  {
1062  dlt_log(LOG_WARNING, "Specified ECUid not found\n");
1063  return -1;
1064  }
1065 
1066  if (connection_status == 1) /* try to connect */
1067  {
1068  if (con->status != DLT_GATEWAY_CONNECTED)
1069  {
1070  if (dlt_client_connect(&con->client, verbose) == 0)
1071  {
1073 
1074  /* setup dlt connection and add to epoll event loop here */
1075  if (dlt_connection_create(daemon_local,
1076  &daemon_local->pEvent,
1077  con->client.sock,
1078  EPOLLIN,
1079  DLT_CONNECTION_GATEWAY) != 0)
1080  {
1081  dlt_log(LOG_ERR, "Gateway connection creation failed\n");
1082  return -1;
1083  }
1084  }
1085  else
1086  {
1087  dlt_log(LOG_ERR, "Could not connect to passive node\n");
1088  return -1;
1089  }
1090  }
1091  else
1092  {
1093  dlt_log(LOG_INFO, "Passive node already connected\n");
1094  }
1095  }
1096  else if (connection_status == 0) /* disconnect*/
1097  {
1098 
1101  daemon_local,
1102  con->client.sock) != 0)
1103  {
1104  dlt_log(LOG_ERR,
1105  "Remove passive node event handler connection failed\n");
1106  }
1107 
1108  if (dlt_client_cleanup(&con->client, verbose) != 0)
1109  {
1110  dlt_log(LOG_ERR, "Could not cleanup DltClient structure\n");
1111  return -1;
1112  }
1113  }
1114  else
1115  {
1116  dlt_log(LOG_ERR, "Unknown command (connection_status)\n");
1117  return -1;
1118  }
1119 
1120  return 0;
1121 }
1122 
1124  DltGateway *gateway,
1125  DltDaemonLocal *daemon_local,
1126  int verbose)
1127 {
1128  int i = 0;
1129  uint32_t len = 0;
1130  DltMessage msg;
1131  char local_str[DLT_DAEMON_TEXTBUFSIZE];
1132 
1133  PRINT_FUNCTION_VERBOSE(verbose);
1134 
1135  if (con == NULL || gateway == NULL || daemon_local == NULL)
1136  {
1137  snprintf(local_str,
1139  "%s: Invalid parameter given\n", __func__);
1140  dlt_log(LOG_WARNING, local_str);
1141  return;
1142  }
1143 
1144  for (i = 0; i < DLT_GATEWAY_MAX_STARTUP_CTRL_MSG; i++)
1145  {
1146  if (con->control_msgs[i] == 0)
1147  {
1148  break; /* no (more) control message to be send */
1149  }
1150 
1151  memset(&msg, 0, sizeof(msg));
1152 
1153  if (dlt_message_init(&msg, verbose) == -1)
1154  {
1155  snprintf(local_str,
1157  "Initialization of message failed\n");
1158  dlt_log(LOG_WARNING, local_str);
1159  return;
1160  }
1161 
1163  {
1164  DltServiceGetLogInfoRequest *req;
1165  msg.databuffer = (uint8_t *)
1166  malloc(sizeof(DltServiceGetLogInfoRequest));
1167  if (msg.databuffer == NULL)
1168  {
1169  snprintf(local_str,
1171  "Initialization of 'GetLogInfo' failed\n");
1172  dlt_log(LOG_WARNING, local_str);
1173  dlt_message_free(&msg, verbose);
1174  return;
1175  }
1176 
1177  req = (DltServiceGetLogInfoRequest *)msg.databuffer;
1178  req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
1179  req->options = 7;
1180  dlt_set_id(req->apid, "");
1181  dlt_set_id(req->ctid, "");
1182  dlt_set_id(req->com, "remo");
1183 
1184  msg.databuffersize = sizeof(DltServiceGetLogInfoRequest);
1185  msg.datasize = msg.databuffersize;
1186  }
1188  {
1189  DltServiceGetSoftwareVersion *req;
1190 
1191  msg.databuffer = (uint8_t *)
1192  malloc(sizeof(DltServiceGetSoftwareVersion));
1193  if (msg.databuffer == NULL)
1194  {
1195  snprintf(local_str,
1197  "Initialization of 'GetSoftwareVersion' failed\n");
1198  dlt_log(LOG_WARNING, local_str);
1199  dlt_message_free(&msg, verbose);
1200  return;
1201  }
1202 
1203  req = (DltServiceGetSoftwareVersion *)msg.databuffer;
1204  req->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
1205 
1207  msg.datasize = msg.databuffersize;
1208  }
1209  else
1210  {
1211  snprintf(local_str,
1213  "Unknown control message. Skip.\n");
1214  dlt_log(LOG_WARNING, local_str);
1215  dlt_message_free(&msg, verbose);
1216  return;
1217  }
1218 
1219  /* prepare storage header */
1220  msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
1221 
1223  {
1224  dlt_message_free(&msg,0);
1225  return;
1226  }
1227 
1228  /* prepare standard header */
1229  msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
1231 
1232  #if (BYTE_ORDER==BIG_ENDIAN)
1233  msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
1234  #endif
1235 
1236  msg.standardheader->mcnt = 0;
1237 
1238  /* Set header extra parameters */
1239  dlt_set_id(msg.headerextra.ecu,"");
1240  //msg.headerextra.seid = 0;
1241  msg.headerextra.tmsp = dlt_uptime();
1242 
1243  /* Copy header extra parameters to headerbuffer */
1245  {
1246  dlt_message_free(&msg,0);
1247  return;
1248  }
1249 
1250  /* prepare extended header */
1251  msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer +
1252  sizeof(DltStorageHeader) +
1253  sizeof(DltStandardHeader) +
1255 
1257 
1258  msg.extendedheader->noar = 1; /* number of arguments */
1259 
1260  dlt_set_id(msg.extendedheader->apid, "APP");
1261  dlt_set_id(msg.extendedheader->ctid, "CON");
1262 
1263  /* prepare length information */
1264  msg.headersize = sizeof(DltStorageHeader) +
1265  sizeof(DltStandardHeader) +
1266  sizeof(DltExtendedHeader) +
1268 
1269  len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize;
1270  if (len>UINT16_MAX)
1271  {
1272  fprintf(stderr,"Critical: Huge injection message discarded!\n");
1273  dlt_message_free(&msg,0);
1274 
1275  return;
1276  }
1277 
1278  msg.standardheader->len = DLT_HTOBE_16(len);
1279 
1280  /* forward message to passive node */
1282  daemon_local,
1283  &msg,
1284  con->ecuid,
1285  verbose) != 0)
1286  {
1287  snprintf(local_str,
1289  "Failed to forward message to passive node.\n");
1290  dlt_log(LOG_WARNING, local_str);
1291  }
1292 
1293  dlt_message_free(&msg, verbose);
1294  }
1295 }
int32_t datasize
Definition: dlt_common.h:423
STATIC int dlt_gateway_check_send_serial(DltGatewayConnection *con, char *value)
Definition: dlt_gateway.c:225
int dlt_message_read(DltMessage *msg, uint8_t *buffer, unsigned int length, int resync, int verbose)
Definition: dlt_common.c:1091
#define DLT_HTYP_UEH
Definition: dlt_protocol.h:82
int dlt_receiver_receive_socket(DltReceiver *receiver)
Definition: dlt_common.c:2173
#define DLT_GATEWAY_RECONNECT_MAX
#define PRINT_FUNCTION_VERBOSE(_verbose)
Definition: dlt_common.h:220
int dlt_config_file_get_section_name(const DltConfigFile *file, int num, char *name)
STATIC int dlt_gateway_check_control_messages(DltGatewayConnection *con, char *value)
Definition: dlt_gateway.c:244
int sock
Definition: dlt_client.h:92
#define DLT_ID_SIZE
Definition: dlt_common.h:204
int dlt_event_handler_unregister_connection(DltEventHandler *evhdl, DltDaemonLocal *daemon_local, int fd)
Unregisters a connection from the event handler and destroys it.
int8_t found_serialheader
Definition: dlt_common.h:416
#define DLT_HTOBE_16(x)
Definition: dlt_common.h:148
DltStorageHeader * storageheader
Definition: dlt_common.h:432
int dlt_gateway_store_connection(DltGateway *gateway, DltGatewayConnection *tmp, int verbose)
Definition: dlt_gateway.c:369
int dlt_gateway_process_gateway_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
Definition: dlt_gateway.c:914
connection_status
#define DLT_MSIN_CONTROL_REQUEST
Definition: dlt_protocol.h:141
int(* func)(DltGatewayConnection *con, char *value)
Definition: dlt_gateway.c:50
int dlt_config_file_get_num_sections(const DltConfigFile *file, int *num)
#define DLT_HTYP_PROTOCOL_VERSION1
Definition: dlt_protocol.h:95
void dlt_set_id(char *id, const char *text)
Definition: dlt_common.c:324
STATIC int dlt_gateway_check_timeout(DltGatewayConnection *con, char *value)
Definition: dlt_gateway.c:201
#define DLT_HTYP_WEID
Definition: dlt_protocol.h:84
#define DLT_CONFIG_FILE_ENTRY_MAX_LEN
DltConfigFile * dlt_config_file_init(char *file_name)
int dlt_client_set_server_ip(DltClient *client, char *ipaddr)
Definition: dlt_client.c:839
int dlt_gateway_establish_connections(DltGateway *gateway, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt_gateway.c:636
int dlt_gateway_configure(DltGateway *gateway, char *config_file, int verbose)
Definition: dlt_gateway.c:455
DltReturnValue dlt_client_init_port(DltClient *client, int port, int verbose)
Definition: dlt_client.c:109
#define DLT_MESSAGE_ERROR_OK
Definition: dlt_common.h:710
#define DLT_STANDARD_HEADER_EXTRA_SIZE(htyp)
Definition: dlt_common.h:213
DltReturnValue dlt_receiver_remove(DltReceiver *receiver, int size)
Definition: dlt_common.c:2232
int dlt_gateway_process_on_demand_request(DltGateway *gateway, DltDaemonLocal *daemon_local, char *node_id, int connection_status, int verbose)
Definition: dlt_gateway.c:1034
char * buf
Definition: dlt_common.h:678
#define DLT_SERVICE_ID_SET_LOG_LEVEL
Definition: dlt_protocol.h:176
#define DLT_SERVICE_ID_GET_LOG_INFO
Definition: dlt_protocol.h:178
#define DLT_DAEMON_ERROR_OK
Definition: dlt-daemon.h:170
DltReturnValue dlt_log(int prio, char *s)
Definition: dlt_common.c:2029
int control_msgs[DLT_GATEWAY_MAX_STARTUP_CTRL_MSG]
DltReturnValue dlt_message_init(DltMessage *msg, int verbose)
Definition: dlt_common.c:666
#define DLT_HTYP_MSBF
Definition: dlt_protocol.h:83
int32_t bytesRcvd
Definition: dlt_common.h:675
DltReturnValue dlt_receiver_move_to_begin(DltReceiver *receiver)
Definition: dlt_common.c:2257
DltExtendedHeader * extendedheader
Definition: dlt_common.h:435
void dlt_gateway_send_control_message(DltGatewayConnection *con, DltGateway *gateway, DltDaemonLocal *daemon_local, int verbose)
Definition: dlt_gateway.c:1123
DltDaemonFlags flags
Definition: dlt-daemon.h:138
int dlt_gateway_process_passive_node_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *receiver, int verbose)
Definition: dlt_gateway.c:731
DltEventHandler pEvent
Definition: dlt-daemon.h:140
connection_trigger trigger
STATIC int dlt_gateway_check_port(DltGatewayConnection *con, char *value)
Definition: dlt_gateway.c:112
DltReceiver receiver
Definition: dlt_client.h:91
STATIC DltGatewayConf configuration_entries[GW_CONF_COUNT]
Definition: dlt_gateway.c:302
DltReturnValue dlt_message_set_extraparameters(DltMessage *msg, int verbose)
Definition: dlt_common.c:1273
STATIC int dlt_gateway_check_ecu(DltGatewayConnection *con, char *value)
Definition: dlt_gateway.c:144
DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu)
Definition: dlt_common.c:2315
int32_t databuffersize
Definition: dlt_common.h:429
DltReturnValue dlt_receiver_init(DltReceiver *receiver, int fd, int buffersize)
Definition: dlt_common.c:2126
#define DLT_HTYP_WTMS
Definition: dlt_protocol.h:86
DltReturnValue dlt_client_cleanup(DltClient *client, int verbose)
Definition: dlt_client.c:301
uint32_t dlt_uptime(void)
Definition: dlt_common.c:3274
DltReturnValue dlt_client_connect(DltClient *client, int verbose)
Definition: dlt_client.c:168
DltGatewayConnection * connections
int dlt_gateway_forward_control_message(DltGateway *gateway, DltDaemonLocal *daemon_local, DltMessage *msg, char *ecu, int verbose)
Definition: dlt_gateway.c:957
char gatewayConfigFile[DLT_DAEMON_FLAG_MAX]
Definition: dlt-daemon.h:127
int32_t headersize
Definition: dlt_common.h:422
int dlt_daemon_client_send(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, void *storage_header, int storage_header_size, void *data1, int size1, void *data2, int size2, int verbose)
const char dltSerialHeader[DLT_ID_SIZE]
Definition: dlt_common.c:70
DltReceiver * dlt_gateway_get_connection_receiver(DltGateway *gateway, int fd)
Definition: dlt_gateway.c:710
STATIC int dlt_gateway_check_connect_trigger(DltGatewayConnection *con, char *value)
Definition: dlt_gateway.c:168
uint8_t headerbuffer[sizeof(DltStorageHeader)+sizeof(DltStandardHeader)+sizeof(DltStandardHeaderExtra)+sizeof(DltExtendedHeader)]
Definition: dlt_common.h:427
#define DLT_DAEMON_SEND_TO_ALL
DltStandardHeaderExtra headerextra
Definition: dlt_common.h:434
int dlt_config_file_get_value(const DltConfigFile *file, const char *section, const char *key, char *value)
connection_status status
#define DLT_DAEMON_RCVBUFSIZESOCK
STATIC int dlt_gateway_check_param(DltGateway *gateway, DltGatewayConnection *con, DltGatewayConfType ctype, char *value)
Definition: dlt_gateway.c:345
DltGatewayConfType
Definition: dlt_gateway.c:54
int dlt_gateway_init(DltDaemonLocal *daemon_local, int verbose)
Definition: dlt_gateway.c:577
DltStandardHeader * standardheader
Definition: dlt_common.h:433
DltReturnValue dlt_message_free(DltMessage *msg, int verbose)
Definition: dlt_common.c:691
DltGateway pGateway
Definition: dlt-daemon.h:141
#define DLT_GATEWAY_MAX_STARTUP_CTRL_MSG
uint8_t * databuffer
Definition: dlt_common.h:428
#define STATIC
Definition: dlt_common.h:343
#define DLT_DAEMON_TCP_PORT
Definition: dlt_common.h:192
#define DLT_SERVICE_ID_LAST_ENTRY
Definition: dlt_protocol.h:196
#define DLT_DAEMON_TEXTBUFSIZE
#define DLT_SERVICE_ID_GET_SOFTWARE_VERSION
Definition: dlt_protocol.h:194
void dlt_config_file_release(DltConfigFile *file)
int dlt_connection_create(DltDaemonLocal *daemon_local, DltEventHandler *evh, int fd, int mask, DltConnectionType type)
Creates a connection and registers it to the DltEventHandler.
void dlt_gateway_deinit(DltGateway *gateway, int verbose)
Definition: dlt_gateway.c:613
#define NULL
Definition: dlt_common.h:232
STATIC int dlt_gateway_check_ip(DltGatewayConnection *con, char *value)
Definition: dlt_gateway.c:72