automotive-dlt
dlt-test-multi-process-client.c
Go to the documentation of this file.
1 /*
2  * @licence app begin@
3  * SPDX license identifier: MPL-2.0
4  *
5  * Copyright (C) 2011-2015, BMW AG
6  *
7  * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
8  *
9  * This Source Code Form is subject to the terms of the
10  * Mozilla Public License (MPL), v. 2.0.
11  * If a copy of the MPL was not distributed with this file,
12  * You can obtain one at http://mozilla.org/MPL/2.0/.
13  *
14  * For further information see http://www.genivi.org/.
15  * @licence end@
16  */
17 
27 /*******************************************************************************
28  ** **
29  ** SRC-MODULE: dlt-test-multi-process-client.c **
30  ** **
31  ** TARGET : linux **
32  ** **
33  ** PROJECT : DLT **
34  ** **
35  ** AUTHOR : Lassi Marttala <Lassi.LM.Marttala@partner.bmw.de> **
36  ** **
37  ** PURPOSE : Receive, validate and measure data from multi process tester **
38  ** **
39  ** REMARKS : **
40  ** **
41  ** PLATFORM DEPENDANT [yes/no]: yes **
42  ** **
43  ** TO BE CHANGED BY USER [yes/no]: no **
44  ** **
45  *******************************************************************************/
46 // System includes
47 #include <string.h>
48 #include <stdio.h>
49 #include <unistd.h>
50 #include <ctype.h>
51 #include <stdlib.h>
52 #include <time.h>
53 #include <fcntl.h>
54 #include <sys/uio.h>
55 #include <sys/stat.h>
56 
57 // DLT Library includes
58 #include "dlt_client.h"
59 #include "dlt_protocol.h"
60 #include "dlt_user.h"
61 // PRivate includes
62 #include "dlt-test-multi-process.h"
63 
64 // Local data structures
65 typedef struct {
67  int verbose;
68  int serial;
69  int baudrate;
70  char *output;
74 } s_parameters;
75 
76 typedef struct {
82 } s_statistics;
83 
84 // Forward declarations
85 int receive(DltMessage *msg, void *data);
86 
90 void usage(char *name) {
91  char version[255];
92  dlt_get_version(version,255);
93 
94  printf("Usage: %s [options] <remote address|serial device>\n", name);
95  printf("Receive messages from dlt-test-multi-process.\n");
96  printf("%s", version);
97  printf("Options:\n");
98  printf(" -m Total messages to receive. (Default: 10000)\n");
99  printf(" -y Serial device mode.\n");
100  printf(" -b baudrate Serial device baudrate. (Default: 115200)\n");
101  printf(" -v Verbose. Increases the verbosity level of dlt client library.\n");
102  printf(" -o filename Output messages in new DLT file.\n");
103 }
104 
108 void init_params(s_parameters *params) {
109  params->max_messages = 10000;
110  params->verbose = 0;
111  params->serial = 0;
112  params->output = NULL;
113  params->output_handle = -1;
114  params->baudrate = 115200;
115 }
116 
120 int read_params(s_parameters *params, int argc, char *argv[]) {
121  init_params(params);
122  int c;
123  opterr = 0;
124  while ((c = getopt(argc, argv, "m:yb:vo:")) != -1) {
125  switch (c) {
126  case 'm':
127  params->max_messages = atoi(optarg);
128  break;
129  case 'y':
130  params->serial = 1;
131  break;
132  case 'b':
133  params->baudrate = atoi(optarg);
134  break;
135  case 'v':
136  params->verbose = 1;
137  break;
138  case 'o':
139  params->output = optarg;
140  break;
141  case '?':
142  if(optopt == 'm' || optopt == 'b' || optopt == 'o')
143  {
144  fprintf(stderr, "Option -%c requires an argument.\n", optopt);
145  }
146  if (isprint(optopt)) {
147  fprintf(stderr, "Unknown option '-%c'.\n", optopt);
148  } else {
149  fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt);
150  }
151  return -1;
152  break;
153  default:
154  return -1;
155  }
156  }
157  return 0;
158 }
159 
163 int init_dlt_connect(DltClient *client, const s_parameters *params, int argc, char *argv[]) {
164  char id[4];
165  if (argc < 2)
166  return -1;
167  if(params->serial > 0)
168  {
169  client->mode = 1;
170  if(dlt_client_set_serial_device(client, argv[argc - 1]) == -1)
171  {
172  fprintf(stderr,"set serial device didn't succeed\n");
173  return -1;
174  }
175  dlt_client_setbaudrate(client, params->baudrate);
176  }
177  else
178  {
179  if(dlt_client_set_server_ip(client, argv[argc - 1]) == -1)
180  {
181  fprintf(stderr,"set serial ip didn't succeed\n");
182  return -1;
183  }
184  }
185  dlt_set_id(id, ECUID);
186  return 0;
187 }
188 
192 int main(int argc, char *argv[]) {
193  s_parameters params;
195  params.client_ref = &client;
196  int err = read_params(&params, argc, argv);
197 
198  if (err != 0) {
199  usage(argv[0]);
200  return err;
201  }
202 
203  dlt_client_init(&client, params.verbose);
205 
206  err = init_dlt_connect(&client, &params, argc, argv);
207  if (err != 0) {
208  usage(argv[0]);
209  return err;
210  }
211 
212  err = dlt_client_connect(&client, params.verbose);
213  if (err != DLT_RETURN_OK) {
214  printf("Failed to connect %s.\n", client.mode > 0 ? client.serialDevice : client.servIP);
215  return err;
216  }
217 
218  if(params.output)
219  {
220  params.output_handle = open(params.output,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
221 
222  if (params.output_handle == -1)
223  {
224  fprintf(stderr,"Failed to open %s for writing.\n",params.output);
225  return -1;
226  }
227  }
228 
229  params.messages_left = params.max_messages;
230 
231  dlt_client_main_loop(&client, &params, params.verbose);
232 
233  if(params.output_handle > 0)
234  {
235  close(params.output_handle);
236  }
237  return 0;
238 }
239 
244 {
245  static int last_print_time;
246  if(last_print_time >= time(NULL) && // Only print once a second
247  (stats.messages_received+stats.broken_messages_received) % 1000 != 0 &&
248  params.messages_left != 0) // Print also every 1000th message
249  {
250  return;
251  }
252  printf("\033[2J\033[1;1H"); // Clear screen.
253  printf("Statistics:\n");
254  printf(" Messages received : %d\n", stats.messages_received);
255  printf(" Broken messages received : %d\n", stats.broken_messages_received);
256  printf(" Bytes received : %d\n", stats.bytes_received);
257  printf(" Time running (seconds) : %ld\n", time(NULL)-stats.first_message_time);
258  printf(" Throughput (msgs/sec)/(B/sec) : %ld/%ld\n",
259  stats.messages_received/((time(NULL)-stats.first_message_time)+1),
260  (stats.bytes_received)/((time(NULL)-stats.first_message_time)+1));
261  if(params.messages_left == 0)
262  {
263  if(stats.broken_messages_received == 0)
264  printf("All messages received succesfully!\n");
265  else
266  printf("Test failure! There were %d broken messages.", stats.broken_messages_received);
267 
268  }
269  fflush(stdout);
270  last_print_time = time(NULL);
271 }
275 int receive(DltMessage *msg, void *data) {
276  static s_statistics stats;
277  char apid[5];
278  struct iovec iov[2];
279  s_parameters *params = (s_parameters *)data;
280 
281  memset(apid, 0, 5);
282  memcpy(apid, msg->extendedheader->apid, 4);
283 
284  if(apid[0] != 'M' || apid[1] != 'T') // TODO: Check through the app description
285  return 0;
286 
287  params->messages_left--;
288 
289  if(stats.first_message_time == 0)
290  {
291  stats.first_message_time = time(NULL);
292  }
293 
294  int buflen = msg->datasize + 1;
295  char *buf = malloc(buflen);
296  if(buf==0)
297  {
298  printf("Out of memory\n");
299  return -1;
300  }
301  memset(buf, 0, buflen);
302 
303  dlt_message_payload(msg,buf,buflen-1,DLT_OUTPUT_ASCII,0);
304 
305  if(strcmp(buf, PAYLOAD_DATA) == 0)
306  {
307  stats.messages_received++;
308  }
309  else
310  {
311  stats.broken_messages_received++;
312  }
313  stats.bytes_received += msg->datasize+msg->headersize-sizeof(DltStorageHeader);;
314 
315  free(buf);
316 
317  print_stats(stats, *params);
318 
319  if (params->output_handle > 0)
320  {
321  iov[0].iov_base = msg->headerbuffer;
322  iov[0].iov_len = msg->headersize;
323  iov[1].iov_base = msg->databuffer;
324  iov[1].iov_len = msg->datasize;
325 
326  stats.output_bytes += writev(params->output_handle, iov, 2);
327  }
328  if(params->messages_left < 1)
329  {
330  dlt_client_cleanup(params->client_ref, params->verbose);
331  }
332  return 0;
333 }
int32_t datasize
Definition: dlt_common.h:423
void print_stats(s_statistics stats, s_parameters params)
void dlt_set_id(char *id, const char *text)
Definition: dlt_common.c:324
void dlt_client_register_message_callback(int(*registerd_callback)(DltMessage *message, void *data))
Definition: dlt_client.c:105
DltReturnValue dlt_client_main_loop(DltClient *client, void *data, int verbose)
Definition: dlt_client.c:326
int dlt_client_set_server_ip(DltClient *client, char *ipaddr)
Definition: dlt_client.c:839
#define ECUID
static DltClient client
DltReturnValue dlt_client_setbaudrate(DltClient *client, int baudrate)
Definition: dlt_client.c:827
DltExtendedHeader * extendedheader
Definition: dlt_common.h:435
int dlt_client_set_serial_device(DltClient *client, char *serial_device)
Definition: dlt_client.c:850
static char data[kDataSize]
Definition: city-test.cc:40
DltReturnValue dlt_client_init(DltClient *client, int verbose)
Definition: dlt_client.c:133
DltReturnValue dlt_client_cleanup(DltClient *client, int verbose)
Definition: dlt_client.c:301
DltReturnValue dlt_client_connect(DltClient *client, int verbose)
Definition: dlt_client.c:168
int init_dlt_connect(DltClient *client, const s_parameters *params, int argc, char *argv[])
int32_t headersize
Definition: dlt_common.h:422
uint8_t headerbuffer[sizeof(DltStorageHeader)+sizeof(DltStandardHeader)+sizeof(DltStandardHeaderExtra)+sizeof(DltExtendedHeader)]
Definition: dlt_common.h:427
int receive(DltMessage *msg, void *data)
void init_params(s_parameters *params)
int main(int argc, char *argv[])
DltReturnValue dlt_message_payload(DltMessage *msg, char *text, int textlength, int type, int verbose)
Definition: dlt_common.c:891
void usage(char *name)
void dlt_get_version(char *buf, size_t size)
Definition: dlt_common.c:3239
char * servIP
Definition: dlt_client.h:93
#define DLT_OUTPUT_ASCII
Definition: dlt_common.h:271
uint8_t * databuffer
Definition: dlt_common.h:428
char * serialDevice
Definition: dlt_client.h:95
#define PAYLOAD_DATA
DltClientMode mode
Definition: dlt_client.h:99
int read_params(s_parameters *params, int argc, char *argv[])
#define NULL
Definition: dlt_common.h:232