diff options
author | João Sousa <48479050+joaodasousa@users.noreply.github.com> | 2020-08-31 00:56:03 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-31 08:56:03 +0900 |
commit | 33fbad18c814e13bd7ba2053525d8959fee437d1 (patch) | |
tree | 87d30704e5e78c603aace4cb2c0dacdf3554eba6 /src | |
parent | 9af27899553dcfe9cd5ffede7f37be57d1a577a6 (diff) | |
download | DLT-daemon-33fbad18c814e13bd7ba2053525d8959fee437d1.tar.gz |
Implement DLTClient for UDP multicast (#240)
* Add UDP multicast support on client side
UDP multicast support is already present on server side. This
patch add seemless support for UDP multicast on client side
in dlt-receive.
Signed-off-by: Joao Sousa <joao.sa.sousa@ctw.bmwgroup.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/console/dlt-receive.c | 19 | ||||
-rw-r--r-- | src/examples/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/lib/dlt_client.c | 82 | ||||
-rw-r--r-- | src/shared/dlt_common.c | 15 |
4 files changed, 113 insertions, 7 deletions
diff --git a/src/console/dlt-receive.c b/src/console/dlt-receive.c index 24280ee..cdfa274 100644 --- a/src/console/dlt-receive.c +++ b/src/console/dlt-receive.c @@ -96,6 +96,7 @@ typedef struct { int mflag; int vflag; int yflag; + int uflag; char *ovalue; char *ovaluebase; /* ovalue without ".dlt" */ char *fvalue; @@ -131,6 +132,7 @@ void usage() printf(" -v Verbose mode\n"); printf(" -h Usage\n"); printf(" -y Serial device mode\n"); + printf(" -u UDP multicast mode\n"); printf(" -b baudrate Serial device baudrate (Default: 115200)\n"); printf(" -e ecuid Set ECU ID (Default: RECV)\n"); printf(" -o filename Output messages in new DLT file\n"); @@ -300,6 +302,7 @@ int main(int argc, char *argv[]) dltdata.mflag = 0; dltdata.vflag = 0; dltdata.yflag = 0; + dltdata.uflag = 0; dltdata.ovalue = 0; dltdata.ovaluebase = 0; dltdata.fvalue = 0; @@ -313,7 +316,7 @@ int main(int argc, char *argv[]) /* Fetch command line arguments */ opterr = 0; - while ((c = getopt (argc, argv, "vashyxmf:o:e:b:c:")) != -1) + while ((c = getopt (argc, argv, "vashyuxmf:o:e:b:c:")) != -1) switch (c) { case 'v': { @@ -350,6 +353,11 @@ int main(int argc, char *argv[]) dltdata.yflag = 1; break; } + case 'u': + { + dltdata.uflag = 1; + break; + } case 'f': { dltdata.fvalue = optarg; @@ -425,9 +433,14 @@ int main(int argc, char *argv[]) dlt_client_register_message_callback(dlt_receive_message_callback); /* Setup DLT Client structure */ - dltclient.mode = dltdata.yflag; + if(dltdata.uflag) { + dltclient.mode = DLT_CLIENT_MODE_UDP_MULTICAST; + } + else { + dltclient.mode = dltdata.yflag; + } - if (dltclient.mode == DLT_CLIENT_MODE_TCP) { + if (dltclient.mode == DLT_CLIENT_MODE_TCP || dltclient.mode == DLT_CLIENT_MODE_UDP_MULTICAST) { for (index = optind; index < argc; index++) if (dlt_client_set_server_ip(&dltclient, argv[index]) == -1) { fprintf(stderr, "set server ip didn't succeed\n"); diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt index 93f76a8..013700d 100644 --- a/src/examples/CMakeLists.txt +++ b/src/examples/CMakeLists.txt @@ -40,8 +40,8 @@ if(WITH_UDP_CONNECTION) set_target_properties(dlt-example-multicast-clientmsg-view PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-example-multicast-clientmsg-view - RUNTIME DESTINATION bin - COMPONENT base) + RUNTIME DESTINATION bin + COMPONENT base) endif(WITH_UDP_CONNECTION) diff --git a/src/lib/dlt_client.c b/src/lib/dlt_client.c index 5c18c0e..0b44d6e 100644 --- a/src/lib/dlt_client.c +++ b/src/lib/dlt_client.c @@ -121,6 +121,7 @@ DltReturnValue dlt_client_init_port(DltClient *client, int port, int verbose) client->receiver.buffer = NULL; client->receiver.buf = NULL; client->receiver.backup_buf = NULL; + client->hostip = NULL; return DLT_RETURN_OK; } @@ -153,16 +154,17 @@ DltReturnValue dlt_client_init(DltClient *client, int verbose) dlt_vlog(LOG_INFO, "Init dlt client struct with default port: %hu.\n", servPort); - return dlt_client_init_port(client, servPort, verbose); } DltReturnValue dlt_client_connect(DltClient *client, int verbose) { + const int yes = 1; char portnumbuffer[33]; struct addrinfo hints, *servinfo, *p; struct sockaddr_un addr; int rv; + struct ip_mreq mreq; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; @@ -266,6 +268,58 @@ DltReturnValue dlt_client_connect(DltClient *client, int verbose) } break; + case DLT_CLIENT_MODE_UDP_MULTICAST: + + if ((client->sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + fprintf(stderr, "ERROR: socket error: %s\n", strerror(errno)); + return DLT_RETURN_ERROR; + } + + /* allow multiple sockets to use the same PORT number */ + if (setsockopt(client->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) + { + fprintf(stderr, "ERROR: Reusing address failed: %s\n", strerror(errno)); + return DLT_RETURN_ERROR; + } + + memset(&client->receiver.addr, 0, sizeof(client->receiver.addr)); + client->receiver.addr.sin_family = AF_INET; + client->receiver.addr.sin_addr.s_addr = htonl(INADDR_ANY); + client->receiver.addr.sin_port = htons(client->port); + + /* bind to receive address */ + if (bind(client->sock, (struct sockaddr*) &client->receiver.addr, sizeof(client->receiver.addr)) < 0) + { + fprintf(stderr, "ERROR: bind failed: %s\n", strerror(errno)); + return DLT_RETURN_ERROR; + } + + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if (client->hostip) + { + mreq.imr_interface.s_addr = inet_addr(client->hostip); + } + if (client->servIP == NULL) + { + fprintf(stderr, "ERROR: server address not set\n"); + return DLT_RETURN_ERROR; + } + + mreq.imr_multiaddr.s_addr = inet_addr(client->servIP); + if (mreq.imr_multiaddr.s_addr == (in_addr_t)-1) + { + fprintf(stderr, "ERROR: server address not not valid %s\n", client->servIP); + return DLT_RETURN_ERROR; + } + + if (setsockopt(client->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) + { + fprintf(stderr, "ERROR: setsockopt add membership failed: %s\n", strerror(errno)); + return DLT_RETURN_ERROR; + } + + break; default: if (verbose) @@ -315,6 +369,10 @@ DltReturnValue dlt_client_cleanup(DltClient *client, int verbose) client->socketPath = NULL; } + if (client->hostip) { + free(client->hostip); + client->hostip = NULL; + } return ret; } @@ -875,6 +933,16 @@ DltReturnValue dlt_client_setbaudrate(DltClient *client, int baudrate) return DLT_RETURN_OK; } +DltReturnValue dlt_client_set_mode(DltClient *client, DltClientMode mode) +{ + if (client == 0) + return DLT_RETURN_ERROR; + + client->mode = mode; + return DLT_RETURN_OK; + +} + int dlt_client_set_server_ip(DltClient *client, char *ipaddr) { client->servIP = strdup(ipaddr); @@ -887,6 +955,18 @@ int dlt_client_set_server_ip(DltClient *client, char *ipaddr) return DLT_RETURN_OK; } +int dlt_client_set_host_if_address(DltClient *client, char *hostip) +{ + client->hostip = strdup(hostip); + + if (client->hostip == NULL) { + dlt_log(LOG_ERR, "ERROR: failed to duplicate UDP interface address\n"); + return DLT_RETURN_ERROR; + } + + return DLT_RETURN_OK; +} + int dlt_client_set_serial_device(DltClient *client, char *serial_device) { client->serialDevice = strdup(serial_device); diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c index eb620f5..823bca7 100644 --- a/src/shared/dlt_common.c +++ b/src/shared/dlt_common.c @@ -2014,6 +2014,8 @@ DltReturnValue dlt_receiver_free_unix_socket(DltReceiver *receiver) int dlt_receiver_receive(DltReceiver *receiver, DltReceiverType from_src) { + socklen_t addrlen; + if (receiver == NULL) return -1; @@ -2035,12 +2037,23 @@ int dlt_receiver_receive(DltReceiver *receiver, DltReceiverType from_src) receiver->buf + receiver->lastBytesRcvd, receiver->buffersize - receiver->lastBytesRcvd, 0); - else + else if (from_src == DLT_RECEIVE_FD) /* wait for data from fd */ receiver->bytesRcvd = read(receiver->fd, receiver->buf + receiver->lastBytesRcvd, receiver->buffersize - receiver->lastBytesRcvd); + else { + /* wait for data from UDP socket */ + addrlen = sizeof(receiver->addr); + receiver->bytesRcvd = recvfrom(receiver->fd, + receiver->buf + receiver->lastBytesRcvd, + receiver->buffersize - receiver->lastBytesRcvd, + 0, + (struct sockaddr *)&(receiver->addr), + &addrlen); + } + if (receiver->bytesRcvd <= 0) { receiver->bytesRcvd = 0; |