diff options
author | Christian Muck <christian.muck@bmw.de> | 2011-04-11 15:41:05 +0200 |
---|---|---|
committer | Christian Muck <christian.muck@bmw.de> | 2011-04-11 15:41:05 +0200 |
commit | 760fb8a4daba3e403376099ce38aca8f88d695d3 (patch) | |
tree | 36b6f428cee8ba0af0fd50b3e44a3d4da9083a44 /src/lib/dlt_client.c | |
parent | 5394c6fa5bf40d9bc8619026cbc4c306211a8499 (diff) | |
download | DLT-daemon-760fb8a4daba3e403376099ce38aca8f88d695d3.tar.gz |
Init of dlt daemon
Diffstat (limited to 'src/lib/dlt_client.c')
-rwxr-xr-x | src/lib/dlt_client.c | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/src/lib/dlt_client.c b/src/lib/dlt_client.c new file mode 100755 index 0000000..87aa273 --- /dev/null +++ b/src/lib/dlt_client.c @@ -0,0 +1,452 @@ +/* + * Dlt- Diagnostic Log and Trace client library + * @licence app begin@ + * + * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de> + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + * Public License, version 2.1, for more details. + * + * You should have received a copy of the GNU Lesser General Public License, version 2.1, along + * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>. + * + * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may + * also be applicable to programs even in cases in which the program is not a library in the technical sense. + * + * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may + * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to + * license your linked modules under the GNU Lesser General Public License, version 2.1, you + * may use the program under the following exception. + * + * As a special exception, the copyright holders of DLT give you permission to combine DLT + * with software programs or libraries that are released under any license unless such a combination is not + * permitted by the license of such a software program or library. You may copy and distribute such a + * system following the terms of the GNU Lesser General Public License, version 2.1, including this + * special exception, for DLT and the licenses of the other code concerned. + * + * Note that people who make modified versions of DLT are not obligated to grant this special exception + * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, + * version 2.1, gives permission to release a modified version without this exception; this exception + * also makes it possible to release a modified version which carries forward this exception. + * + * @licence end@ + */ + +/******************************************************************************* +** ** +** SRC-MODULE: dlt_client.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision$ + * $LastChangedDate$ + * $LastChangedBy$ + Initials Date Comment + aw 12.07.2010 initial + */ + +#include <stdio.h> + +#if defined (__WIN32__) || defined (_MSC_VER) +#pragma warning(disable : 4996) /* Switch off C4996 warnings */ +#include <winsock2.h> /* for socket(), connect(), send(), and recv() */ +#else +#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */ +#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */ +#include <netdb.h> +#include <sys/stat.h> +#endif + +#if defined(_MSC_VER) +#include <io.h> +#else +#include <unistd.h> +#include <syslog.h> +#endif + +#include <fcntl.h> + +#include <stdlib.h> /* for malloc(), free() */ +#include <string.h> /* for strlen(), memcmp(), memmove() */ +#include <errno.h> + +#include "dlt_types.h" +#include "dlt_client.h" +#include "dlt_client_cfg.h" + +static int (*message_callback_function) (DltMessage *message, void *data) = NULL; + +void dlt_client_register_message_callback(int (*registerd_callback) (DltMessage *message, void *data)){ + message_callback_function = registerd_callback; +} + +int dlt_client_init(DltClient *client, int verbose) +{ + if (client==0) + { + return -1; + } + + client->sock=-1; + client->servIP=0; + client->serialDevice=0; + client->baudrate=DLT_CLIENT_INITIAL_BAUDRATE; + client->serial_mode=0; + client->receiver.buffer=0; + + return 0; +} + +int dlt_client_connect(DltClient *client, int verbose) +{ + struct sockaddr_in servAddr; + unsigned short servPort = DLT_DAEMON_TCP_PORT; + struct hostent *host; /* Structure containing host information */ + + if (client==0) + { + return -1; + } + + if (client->serial_mode==0) + { + /* open socket */ + if ((client->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + { + fprintf(stderr,"ERROR: socket() failed!\n"); + return -1; + } + + if ((host = (struct hostent*) gethostbyname(client->servIP)) == 0) + { + fprintf(stderr, "ERROR: gethostbyname() failed\n"); + return -1; + } + + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*( struct in_addr*)( host -> h_addr_list[0]))); + servAddr.sin_port = htons(servPort); + + if (connect(client->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + { + fprintf(stderr,"ERROR: connect() failed!\n"); + return -1; + } + + if (verbose) + { + printf("Connected to DLT daemon (%s)\n",client->servIP); + } + } + else + { + /* open serial connection */ + client->sock=open(client->serialDevice,O_RDWR); + if (client->sock<0) + { + fprintf(stderr,"ERROR: Failed to open device %s\n", client->serialDevice); + return -1; + } + + if (isatty(client->sock)) + { + #if !defined (__WIN32__) + if (dlt_setup_serial(client->sock,client->baudrate)<0) + { + fprintf(stderr,"ERROR: Failed to configure serial device %s (%s) \n", client->serialDevice, strerror(errno)); + return -1; + } + #else + return -1; + #endif + } + else + { + if (verbose) + { + fprintf(stderr,"ERROR: Device is not a serial device, device = %s (%s) \n", client->serialDevice, strerror(errno)); + } + return -1; + } + + if (verbose) + { + printf("Connected to %s\n", client->serialDevice); + } + } + + if (dlt_receiver_init(&(client->receiver),client->sock,DLT_CLIENT_RCVBUFSIZE)!=0) + { + return -1; + } + + return 0; +} + +int dlt_client_cleanup(DltClient *client, int verbose) +{ + if (client==0) + { + return -1; + } + + if (client->sock!=-1) + { + close(client->sock); + } + + if (dlt_receiver_free(&(client->receiver))==-1) + { + return -1; + } + + return 0; +} + +int dlt_client_main_loop(DltClient *client, void *data, int verbose) +{ + DltMessage msg; + int ret; + + if (client==0) + { + return -1; + } + + if (dlt_message_init(&msg,verbose)==-1) + { + return -1; + } + + while (1) + { + if (client->serial_mode==0) + { + /* wait for data from socket */ + ret = dlt_receiver_receive_socket(&(client->receiver)); + } + else + { + /* wait for data from serial connection */ + ret = dlt_receiver_receive_fd(&(client->receiver)); + } + + if (ret<=0) + { + /* No more data to be received */ + if (dlt_message_free(&msg,verbose)==-1) + { + return -1; + } + + return 1; + } + + while (dlt_message_read(&msg,(unsigned char*)(client->receiver.buf),client->receiver.bytesRcvd,0,verbose)==0) + { + /* Call callback function */ + if (message_callback_function) + { + (*message_callback_function)(&msg,data); + } + + if (msg.found_serialheader) + { + if (dlt_receiver_remove(&(client->receiver),msg.headersize+msg.datasize-sizeof(DltStorageHeader)+sizeof(dltSerialHeader))==-1) + { + /* Return value ignored */ + dlt_message_free(&msg,verbose); + return -1; + } + } + else + { + if (dlt_receiver_remove(&(client->receiver),msg.headersize+msg.datasize-sizeof(DltStorageHeader))==-1) + { + /* Return value ignored */ + dlt_message_free(&msg,verbose); + return -1; + } + } + } + + if (dlt_receiver_move_to_begin(&(client->receiver))==-1) + { + /* Return value ignored */ + dlt_message_free(&msg,verbose); + return -1; + } + } + + if (dlt_message_free(&msg,verbose)==-1) + { + return -1; + } + + return 0; +} + +int dlt_client_send_inject_msg(DltClient *client, char *apid, char *ctid, uint32_t serviceID, uint8_t *buffer, uint32_t size) +{ + DltMessage msg; + int ret; + int offset=0; + + int32_t len; + + if ((client==0) || (client->sock<0) || (apid==0) || (ctid==0) || (buffer==0) || (size==0) || + (serviceID<DLT_SERVICE_ID_CALLSW_CINJECTION)) + { + return -1; + } + + /* initialise new message */ + if (dlt_message_init(&msg,0)==-1) + { + return -1; + } + + /* prepare payload of data */ + msg.datasize = sizeof(uint32_t) + sizeof(uint32_t) + size; + if (msg.databuffer) + { + free(msg.databuffer); + } + msg.databuffer = (uint8_t *) malloc(msg.datasize); + + memcpy(msg.databuffer , &serviceID,sizeof(serviceID)); + offset+=sizeof(uint32_t); + memcpy(msg.databuffer+offset, &size, sizeof(size)); + offset+=sizeof(uint32_t); + memcpy(msg.databuffer+offset, buffer, size); + + /* prepare storage header */ + msg.storageheader = (DltStorageHeader*)msg.headerbuffer; + + if (dlt_set_storageheader(msg.storageheader,"")==-1) + { + dlt_message_free(&msg,0); + return -1; + } + + /* prepare standard header */ + msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader)); + msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ; + + #if (BYTE_ORDER==BIG_ENDIAN) + msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF); + #endif + + msg.standardheader->mcnt = 0; + + /* Set header extra parameters */ + dlt_set_id(msg.headerextra.ecu,""); + //msg.headerextra.seid = 0; + msg.headerextra.tmsp = dlt_uptime(); + + /* Copy header extra parameters to headerbuffer */ + if (dlt_message_set_extraparameters(&msg,0)==-1) + { + dlt_message_free(&msg,0); + return -1; + } + + /* prepare extended header */ + msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + + sizeof(DltStorageHeader) + + sizeof(DltStandardHeader) + + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) ); + + msg.extendedheader->msin = DLT_MSIN_CONTROL_REQUEST; + + msg.extendedheader->noar = 1; /* number of arguments */ + + dlt_set_id(msg.extendedheader->apid,(apid[0]=='\0')?DLT_CLIENT_DUMMY_APP_ID:apid); + dlt_set_id(msg.extendedheader->ctid,(ctid[0]=='\0')?DLT_CLIENT_DUMMY_CON_ID:ctid); + + /* prepare length information */ + msg.headersize = sizeof(DltStorageHeader) + + sizeof(DltStandardHeader) + + sizeof(DltExtendedHeader) + + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp); + + len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize; + if (len>UINT16_MAX) + { + fprintf(stderr,"Critical: Huge injection message discarded!\n"); + dlt_message_free(&msg,0); + + return -1; + } + + msg.standardheader->len = DLT_HTOBE_16(len); + + /* Send data (without storage header) */ + if (client->serial_mode) + { + /* via FileDescriptor */ + ret=write(client->sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader)); + ret=write(client->sock, msg.databuffer,msg.datasize); + } + else + { + /* via Socket */ + send(client->sock, (const char *)(msg.headerbuffer+sizeof(DltStorageHeader)),msg.headersize-sizeof(DltStorageHeader),0); + send(client->sock, (const char *)msg.databuffer,msg.datasize,0); + } + + /* free message */ + if (dlt_message_free(&msg,0)==-1) + { + return -1; + } + + return 0; +} + +int dlt_client_setbaudrate(DltClient *client, int baudrate) +{ + if (client==0) + { + return -1; + } + + client->baudrate = dlt_convert_serial_speed(baudrate); + + return 0; +} + |