From 976746f28e1c4c0a6ee24bf3f94ce66b890b3898 Mon Sep 17 00:00:00 2001 From: Sunil-K-S <54260601+Sunil-K-S@users.noreply.github.com> Date: Fri, 23 Aug 2019 10:01:08 +0530 Subject: UDP Multicast implementation (#155) The feature can be enabled by setting WITH_UDP_CONNECTION to ON. Signed-off-by: sunil.s --- src/examples/CMakeLists.txt | 13 +- .../dlt-example-multicast-clientmsg-view.c | 197 +++++++++++++++++++++ 2 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 src/examples/dlt-example-multicast-clientmsg-view.c (limited to 'src/examples') diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt index 8e6f390..93f76a8 100644 --- a/src/examples/CMakeLists.txt +++ b/src/examples/CMakeLists.txt @@ -33,7 +33,18 @@ add_executable( dlt-example-filetransfer ${dlt_example_filetransfer_SRCS}) target_link_libraries(dlt-example-filetransfer dlt ) set_target_properties(dlt-example-filetransfer PROPERTIES LINKER_LANGUAGE C) +if(WITH_UDP_CONNECTION) + set(dlt-example-multicast-clientmsg-view_SRCS dlt-example-multicast-clientmsg-view.c) + add_executable(dlt-example-multicast-clientmsg-view ${dlt-example-multicast-clientmsg-view_SRCS} ${dlt_most_SRCS}) + target_link_libraries(dlt-example-multicast-clientmsg-view dlt ) + set_target_properties(dlt-example-multicast-clientmsg-view PROPERTIES LINKER_LANGUAGE C) + + install(TARGETS dlt-example-multicast-clientmsg-view + RUNTIME DESTINATION bin + COMPONENT base) + +endif(WITH_UDP_CONNECTION) + install(TARGETS dlt-example-user dlt-example-user-func dlt-example-user-common-api dlt-example-filetransfer RUNTIME DESTINATION bin COMPONENT base) - diff --git a/src/examples/dlt-example-multicast-clientmsg-view.c b/src/examples/dlt-example-multicast-clientmsg-view.c new file mode 100644 index 0000000..aa3d5af --- /dev/null +++ b/src/examples/dlt-example-multicast-clientmsg-view.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2019 LG Electronics Inc. + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of GENIVI Project DLT - Diagnostic Log and Trace. + * 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/. + */ + +/*! + * \author + * Guruprasad KN + * Sachin Sudhakar Shetty + * Sunil Kovila Sampath + * + * \Copyright (c) 2019 LG Electronics Inc. + * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/. + * + * \file dlt-example-multicast-clientmsg-view.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* for isprint() */ +#include /* for atoi() */ +#include /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */ +#include /* for open() */ +#include /* for writev() */ +#include +#include +#include +#include +#include /* for PATH_MAX */ +#include + +#include "dlt_client.h" +#include "dlt_client_cfg.h" + +#define DLT_RECEIVE_TEXTBUFSIZE 10024 + +#define HELLO_PORT 3491 +#define HELLO_GROUP "225.0.0.37" + +struct clientinfostruct +{ + int fd; + struct sockaddr_in addr; + socklen_t addlen; + DltReceiver receiver; +}; + +int dlt_receiver_receive_socket_udp(struct clientinfostruct *clientinfo, DltReceiver *receiver) +{ + if ((receiver == NULL) || (clientinfo == NULL)) { + printf("NULL receiver or clientinfo in dlt_receiver_receive_socket_udp\n"); + return -1; + } + + if (receiver->buffer == NULL) { + printf("NULL receiver->buffer in dlt_receiver_receive_socket_udp\n"); + return -1; + } + + receiver->buf = (char *)receiver->buffer; + receiver->lastBytesRcvd = receiver->bytesRcvd; + + /* wait for data from socket */ + unsigned int addrlen = sizeof(clientinfo->addr); + + if ((receiver->bytesRcvd = recvfrom(clientinfo->fd, + receiver->buf + receiver->lastBytesRcvd, + receiver->buffersize - receiver->lastBytesRcvd, + 0, + (struct sockaddr *)&(clientinfo->addr), &addrlen)) + <= 0) { + printf("Error\n"); + perror("recvfrom"); + receiver->bytesRcvd = 0; + return receiver->bytesRcvd; + } /* if */ + + receiver->totalBytesRcvd += receiver->bytesRcvd; + receiver->bytesRcvd += receiver->lastBytesRcvd; + + return receiver->bytesRcvd; +} + +int dlt_receive_message_callback_udp(DltMessage *message) +{ + static char text[DLT_RECEIVE_TEXTBUFSIZE]; + + if ((message == NULL)) { + printf("NULL message in dlt_receive_message_callback_udp\n"); + return -1; + } + + /* prepare storage header */ + if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) + dlt_set_storageheader(message->storageheader, message->headerextra.ecu); + else + dlt_set_storageheader(message->storageheader, "ECU1"); + + dlt_message_header(message, text, DLT_RECEIVE_TEXTBUFSIZE, 0); + + printf("%s ", text); + + dlt_message_payload(message, text, DLT_RECEIVE_TEXTBUFSIZE, DLT_OUTPUT_ASCII, 0); + + printf("[%s]\n", text); + + return 0; +} + + +int main() +{ + struct clientinfostruct clientinfo; + struct ip_mreq mreq; + + u_int yes = 1; + + /* create what looks like an ordinary UDP socket */ + if ((clientinfo.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket"); + exit(1); + } + + /* allow multiple sockets to use the same PORT number */ + if (setsockopt(clientinfo.fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { + perror("Reusing ADDR failed"); + exit(1); + } + + /* set up destination address */ + memset(&clientinfo.addr, 0, sizeof(clientinfo.addr)); + clientinfo.addr.sin_family = AF_INET; + clientinfo.addr.sin_addr.s_addr = htonl(INADDR_ANY); /* N.B.: differs from sender */ + clientinfo.addr.sin_port = htons(HELLO_PORT); + + /* bind to receive address */ + if (bind(clientinfo.fd, (struct sockaddr *)&clientinfo.addr, sizeof(clientinfo.addr)) < 0) { + perror("bind"); + exit(1); + } + + /* use setsockopt() to request that the kernel join a multicast group */ + mreq.imr_multiaddr.s_addr = inet_addr(HELLO_GROUP); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + if (setsockopt(clientinfo.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { + perror("setsockopt"); + exit(1); + } + + DltMessage msg; + + if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) + return DLT_RETURN_ERROR; + + if (dlt_receiver_init(&(clientinfo.receiver), clientinfo.fd, + DLT_RECEIVE_BUFSIZE) != DLT_RETURN_OK) + return DLT_RETURN_ERROR; + + printf("Waiting for message on ip %s port : %d\n", HELLO_GROUP, HELLO_PORT); + + while (1) { + /* wait for data from socket */ + dlt_receiver_receive_socket_udp(&clientinfo, &(clientinfo.receiver)); + + while (dlt_message_read(&msg, (unsigned char *)(clientinfo.receiver.buf), + clientinfo.receiver.bytesRcvd, 0, 0) == DLT_MESSAGE_ERROR_OK) { + dlt_receive_message_callback_udp(&msg); + + if (dlt_receiver_remove(&(clientinfo.receiver), + msg.headersize + msg.datasize - sizeof(DltStorageHeader)) + == DLT_RETURN_ERROR) { + /* Return value ignored */ + dlt_message_free(&msg, 0); + return DLT_RETURN_ERROR; + } + } + + if (dlt_receiver_move_to_begin(&(clientinfo.receiver)) == DLT_RETURN_ERROR) { + /* Return value ignored */ + dlt_message_free(&msg, 0); + return DLT_RETURN_ERROR; + } + } +} + -- cgit v1.2.1