2014-06-05 09:34:29 +00:00
|
|
|
/**
|
2014-06-05 09:34:51 +00:00
|
|
|
* Some basic tests
|
2014-06-05 09:34:29 +00:00
|
|
|
*
|
|
|
|
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
|
|
|
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2014-06-05 09:34:40 +00:00
|
|
|
#include <signal.h>
|
|
|
|
#include <time.h>
|
2014-06-05 09:34:51 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <limits.h>
|
2014-06-05 09:34:29 +00:00
|
|
|
|
|
|
|
#include "msg.h"
|
2014-06-05 09:34:51 +00:00
|
|
|
#include "utils.h"
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:40 +00:00
|
|
|
int sd;
|
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
void quit(int sig, siginfo_t *si, void *ptr)
|
2014-06-05 09:34:40 +00:00
|
|
|
{
|
2014-06-05 09:34:51 +00:00
|
|
|
close(sd);
|
2014-06-05 09:34:40 +00:00
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2014-06-05 09:34:29 +00:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2014-06-05 09:34:51 +00:00
|
|
|
struct sockaddr_in sa;
|
|
|
|
|
|
|
|
if (argc != 3) {
|
|
|
|
printf("Usage: %s TEST IP:PORT\n", argv[0]);
|
|
|
|
printf(" TEST has to be 'latency' for now\n");
|
2014-06-05 09:34:29 +00:00
|
|
|
printf(" IP is the destination ip of our packets\n");
|
2014-06-05 09:34:51 +00:00
|
|
|
printf(" PORT is the port to send to\n\n");
|
2014-06-05 09:34:29 +00:00
|
|
|
printf("s2ss Simulator2Simulator Server v%s\n", VERSION);
|
|
|
|
printf("Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
/* Setup signals */
|
|
|
|
struct sigaction sa_quit = {
|
|
|
|
.sa_flags = SA_SIGINFO,
|
|
|
|
.sa_sigaction = quit
|
|
|
|
};
|
|
|
|
|
|
|
|
sigemptyset(&sa_quit.sa_mask);
|
2014-06-05 09:35:10 +00:00
|
|
|
sigaction(SIGTERM, &sa_quit, NULL);
|
2014-06-05 09:34:51 +00:00
|
|
|
sigaction(SIGINT, &sa_quit, NULL);
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
/* Resolve address */
|
|
|
|
if (resolve(argv[2], &sa, 0))
|
|
|
|
error("Failed to resolve: %s", argv[2]);
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
/* Create socket */
|
2014-06-05 09:34:40 +00:00
|
|
|
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
2014-06-05 09:34:29 +00:00
|
|
|
if (sd < 0)
|
2014-06-05 09:35:14 +00:00
|
|
|
perror("Failed to create socket");
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
/* Bind socket */
|
|
|
|
if (bind(sd, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)))
|
|
|
|
error("Failed to bind socket: %s", strerror(errno));
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
/* Connect socket */
|
|
|
|
sa.sin_port = htons(ntohs(sa.sin_port) + 1);
|
|
|
|
if (connect(sd, (struct sockaddr *) &sa, sizeof(struct sockaddr_in))) {
|
|
|
|
error("Failed to connect socket: %s", strerror(errno));
|
|
|
|
}
|
2014-06-05 09:34:40 +00:00
|
|
|
|
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
if (!strcmp(argv[1], "latency")) {
|
|
|
|
struct msg m2, m1 = {
|
|
|
|
.device = 99,
|
|
|
|
.sequence = 0
|
|
|
|
};
|
|
|
|
struct timespec *ts1 = (struct timespec *) &m1.data;
|
|
|
|
struct timespec *ts2 = (struct timespec *) &m2.data;
|
|
|
|
struct timespec *ts3 = malloc(sizeof(struct timespec));
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
long long rtt, rtt_max = LLONG_MIN, rtt_min = LLONG_MAX;
|
|
|
|
long long run = 0, avg = 0;
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
while (1) {
|
|
|
|
clock_gettime(CLOCK_REALTIME, ts1);
|
|
|
|
send(sd, &m1, 8 + m1.length, 0);
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
recv(sd, &m2, sizeof(struct msg), 0);
|
|
|
|
clock_gettime(CLOCK_REALTIME, ts3);
|
2014-06-05 09:34:40 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
rtt = ts3->tv_nsec - ts2->tv_nsec;
|
|
|
|
if (rtt < 0) continue;
|
2014-06-05 09:34:40 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
if (rtt > rtt_max) rtt_max = rtt;
|
|
|
|
if (rtt < rtt_min) rtt_min = rtt;
|
2014-06-05 09:34:40 +00:00
|
|
|
|
2014-06-05 09:34:51 +00:00
|
|
|
avg += rtt;
|
|
|
|
|
2014-06-05 09:35:09 +00:00
|
|
|
info("rtt %.3f min %.3f max %.3f avg %.3f uS\n", 1e-3 * rtt, 1e-3 * rtt_min, 1e-3 * rtt_max, 1e-3 * avg / ++run);
|
2014-06-05 09:34:51 +00:00
|
|
|
|
|
|
|
m1.sequence++;
|
|
|
|
usleep(1000);
|
|
|
|
}
|
|
|
|
}
|
2014-06-05 09:34:29 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|