summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoão Sousa <48479050+joaodasousa@users.noreply.github.com>2020-08-31 00:56:03 +0100
committerGitHub <noreply@github.com>2020-08-31 08:56:03 +0900
commit33fbad18c814e13bd7ba2053525d8959fee437d1 (patch)
tree87d30704e5e78c603aace4cb2c0dacdf3554eba6 /src
parent9af27899553dcfe9cd5ffede7f37be57d1a577a6 (diff)
downloadDLT-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.c19
-rw-r--r--src/examples/CMakeLists.txt4
-rw-r--r--src/lib/dlt_client.c82
-rw-r--r--src/shared/dlt_common.c15
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;