/* * @licence app begin@ * SPDX license identifier: MPL-2.0 * * Copyright (C) 2011-2015, BMW AG * * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. * * This Source Code Form is subject to the terms of the * Mozilla Public License (MPL), v. 2.0. * If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. * * For further information see http://www.genivi.org/. * @licence end@ */ /*! * \author Lassi Marttala * * \copyright Copyright © 2011-2015 BMW AG. \n * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. * * \file dlt-test-multi-process-client.c */ /******************************************************************************* ** ** ** SRC-MODULE: dlt-test-multi-process-client.c ** ** ** ** TARGET : linux ** ** ** ** PROJECT : DLT ** ** ** ** AUTHOR : Lassi Marttala ** ** ** ** PURPOSE : Receive, validate and measure data from multi process tester ** ** ** ** REMARKS : ** ** ** ** PLATFORM DEPENDANT [yes/no]: yes ** ** ** ** TO BE CHANGED BY USER [yes/no]: no ** ** ** *******************************************************************************/ // System includes #include #include #include #include #include #include #include #include #include // DLT Library includes #include "dlt_client.h" #include "dlt_protocol.h" #include "dlt_user.h" // PRivate includes #include "dlt-test-multi-process.h" // Local data structures typedef struct { int max_messages; int verbose; int serial; int baudrate; char *output; int output_handle; int messages_left; DltClient *client_ref; } s_parameters; typedef struct { int messages_received; int broken_messages_received; int bytes_received; int first_message_time; int output_bytes; } s_statistics; // Forward declarations int receive(DltMessage *msg, void *data); /** * Print usage information */ void usage(char *name) { char version[255]; dlt_get_version(version,255); printf("Usage: %s [options] \n", name); printf("Receive messages from dlt-test-multi-process.\n"); printf("%s", version); printf("Options:\n"); printf(" -m Total messages to receive. (Default: 10000)\n"); printf(" -y Serial device mode.\n"); printf(" -b baudrate Serial device baudrate. (Default: 115200)\n"); printf(" -v Verbose. Increases the verbosity level of dlt client library.\n"); printf(" -o filename Output messages in new DLT file.\n"); } /** * Initialize reasonable default parameters. */ void init_params(s_parameters *params) { params->max_messages = 10000; params->verbose = 0; params->serial = 0; params->output = NULL; params->output_handle = -1; params->baudrate = 115200; } /** * Read the command line parameters */ int read_params(s_parameters *params, int argc, char *argv[]) { init_params(params); int c; opterr = 0; while ((c = getopt(argc, argv, "m:yb:vo:")) != -1) { switch (c) { case 'm': params->max_messages = atoi(optarg); break; case 'y': params->serial = 1; break; case 'b': params->baudrate = atoi(optarg); break; case 'v': params->verbose = 1; break; case 'o': params->output = optarg; break; case '?': if(optopt == 'm' || optopt == 'b' || optopt == 'o') { fprintf(stderr, "Option -%c requires an argument.\n", optopt); } if (isprint(optopt)) { fprintf(stderr, "Unknown option '-%c'.\n", optopt); } else { fprintf(stderr, "Unknown option character '\\x%x'.\n", optopt); } return -1; break; default: return -1; } } return 0; } /** * Set the connection parameters for dlt client */ int init_dlt_connect(DltClient *client, const s_parameters *params, int argc, char *argv[]) { char id[4]; if (argc < 2) return -1; if(params->serial > 0) { client->mode = 1; if(dlt_client_set_serial_device(client, argv[argc - 1]) == -1) { fprintf(stderr,"set serial device didn't succeed\n"); return -1; } dlt_client_setbaudrate(client, params->baudrate); } else { if(dlt_client_set_server_ip(client, argv[argc - 1]) == -1) { fprintf(stderr,"set serial ip didn't succeed\n"); return -1; } } dlt_set_id(id, ECUID); return 0; } /** * Entry point */ int main(int argc, char *argv[]) { s_parameters params; DltClient client; params.client_ref = &client; int err = read_params(¶ms, argc, argv); if (err != 0) { usage(argv[0]); return err; } dlt_client_init(&client, params.verbose); dlt_client_register_message_callback(receive); err = init_dlt_connect(&client, ¶ms, argc, argv); if (err != 0) { usage(argv[0]); return err; } err = dlt_client_connect(&client, params.verbose); if (err != DLT_RETURN_OK) { printf("Failed to connect %s.\n", client.mode > 0 ? client.serialDevice : client.servIP); return err; } if(params.output) { params.output_handle = open(params.output,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (params.output_handle == -1) { fprintf(stderr,"Failed to open %s for writing.\n",params.output); return -1; } } params.messages_left = params.max_messages; dlt_client_main_loop(&client, ¶ms, params.verbose); if(params.output_handle > 0) { close(params.output_handle); } return 0; } /** * Print current test statistics */ void print_stats(s_statistics stats, s_parameters params) { static int last_print_time; if(last_print_time >= time(NULL) && // Only print once a second (stats.messages_received+stats.broken_messages_received) % 1000 != 0 && params.messages_left != 0) // Print also every 1000th message { return; } printf("\033[2J\033[1;1H"); // Clear screen. printf("Statistics:\n"); printf(" Messages received : %d\n", stats.messages_received); printf(" Broken messages received : %d\n", stats.broken_messages_received); printf(" Bytes received : %d\n", stats.bytes_received); printf(" Time running (seconds) : %ld\n", time(NULL)-stats.first_message_time); printf(" Throughput (msgs/sec)/(B/sec) : %ld/%ld\n", stats.messages_received/((time(NULL)-stats.first_message_time)+1), (stats.bytes_received)/((time(NULL)-stats.first_message_time)+1)); if(params.messages_left == 0) { if(stats.broken_messages_received == 0) printf("All messages received succesfully!\n"); else printf("Test failure! There were %d broken messages.", stats.broken_messages_received); } fflush(stdout); last_print_time = time(NULL); } /** * Callback for dlt client */ int receive(DltMessage *msg, void *data) { static s_statistics stats; char apid[5]; struct iovec iov[2]; s_parameters *params = (s_parameters *)data; memset(apid, 0, 5); memcpy(apid, msg->extendedheader->apid, 4); if(apid[0] != 'M' || apid[1] != 'T') // TODO: Check through the app description return 0; params->messages_left--; if(stats.first_message_time == 0) { stats.first_message_time = time(NULL); } int buflen = msg->datasize + 1; char *buf = malloc(buflen); if(buf==0) { printf("Out of memory\n"); return -1; } memset(buf, 0, buflen); dlt_message_payload(msg,buf,buflen-1,DLT_OUTPUT_ASCII,0); if(strcmp(buf, PAYLOAD_DATA) == 0) { stats.messages_received++; } else { stats.broken_messages_received++; } stats.bytes_received += msg->datasize+msg->headersize-sizeof(DltStorageHeader);; free(buf); print_stats(stats, *params); if (params->output_handle > 0) { iov[0].iov_base = msg->headerbuffer; iov[0].iov_len = msg->headersize; iov[1].iov_base = msg->databuffer; iov[1].iov_len = msg->datasize; stats.output_bytes += writev(params->output_handle, iov, 2); } if(params->messages_left < 1) { dlt_client_cleanup(params->client_ref, params->verbose); } return 0; }