Commit f58b26e5 authored by Stefan Reif's avatar Stefan Reif

Add time-sender and time-receiver

parent e4cd39e1
Pipeline #2063 failed with stages
in 23 seconds
......@@ -16,6 +16,10 @@ add_subdirectory(util)
add_executable(sender sender.c)
add_executable(receiver receiver.c)
add_executable(time-sender time-sender.c)
add_executable(time-receiver time-receiver.c)
target_link_libraries(sender LINK_PUBLIC PRRT UTIL ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(receiver LINK_PUBLIC PRRT UTIL ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(time-sender LINK_PUBLIC PRRT UTIL ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(time-receiver LINK_PUBLIC PRRT UTIL ${CMAKE_THREAD_LIBS_INIT})
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <argp.h>
#include "util/dbg.h"
#include "proto/socket.h"
PrrtSocket *s = NULL;
static volatile int keepRunning = true;
static char doc[] = "PRRT Receiver";
static struct argp_option options[] = {
{"port", 'p', "PORT", 0, "Target Port" },
{"rounds", 'r', "ROUNDS", 0, "Rounds" },
{"output", 'o', "FILE", 0, "Output to FILE instead of standard output" },
{"threadpinning", 'T', 0, 0, "Enable thread pinning"},
{ 0 }
};
static struct arguments
{
uint16_t port;
uint16_t rounds;
char* outfile;
bool thread_pinning;
};
static char args_doc[] = "";
static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
struct arguments *arguments = state->input;
char* pEnd;
switch (key)
{
case 'p':
arguments->port = (uint16_t) strtol(arg, &pEnd, 10);
break;
case 'r':
arguments->rounds = (uint16_t) strtol(arg, &pEnd, 10);
break;
case 'o':
arguments->outfile = arg;
break;
case 'T':
arguments->thread_pinning = true;
break;
case ARGP_KEY_END:
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
void intHandler(int dummy) {
keepRunning = false;
PrrtSocket_interrupt(s);
}
static long long timedelta(struct timespec *t1, struct timespec *t2)
{
long long delta = t1->tv_sec - t2->tv_sec;
delta *= 1000000000;
delta += t1->tv_nsec - t2->tv_nsec;
return delta;
}
int main(int argc, char **argv) {
signal(SIGINT, intHandler);
struct argp argp = { options, parse_opt, args_doc, doc };
struct arguments arguments = {
.port = 5000,
.rounds = 127,
.outfile = "-",
.thread_pinning = false,
};
argp_parse (&argp, argc, argv, 0, 0, &arguments);
bool file_output = false;
FILE *out_desc = stdout;
if (strcmp(arguments.outfile, "-") != 0) {
file_output = true;
out_desc = fopen(arguments.outfile, "w");
}
uint32_t rounds = arguments.rounds;
#ifdef XLAP
if (rounds >= TS_ROWS) {
printf("Receiver: Too many rounds for use with XLAP (max: %d).\n", TS_ROWS-1);
return -1;
}
#endif
s = PrrtSocket_create(false, HALF_TIMESTAMP-1);
check(s != NULL, "Could not create socket.");
if(arguments.thread_pinning) {
PrrtSocket_enable_thread_pinning(s);
}
check(PrrtSocket_bind(s, "0.0.0.0", arguments.port), "bind failed");
XlapTimestampTable *tstable_data = malloc(sizeof(XlapTimestampTable));
XlapTimestampTable *tstable_redundancy = malloc(sizeof(XlapTimestampTable));
check(tstable_data != NULL, "malloc failed");
check(tstable_redundancy != NULL, "malloc failed");
XlapTimestampTableInstall(s, ts_data_packet, tstable_data);
XlapTimestampTableInstall(s, ts_redundancy_packet, tstable_redundancy);
uint32_t i = 0;
while (i < rounds && keepRunning) {
char buffer[MAX_PAYLOAD_LENGTH + 1];
debug(DEBUG_RECEIVER, "About to receive.");
int n = PrrtSocket_recv(s, buffer);
if (n < 0) {
continue;
}
struct timespec now, old;
clock_gettime(CLOCK_REALTIME, &now);
memcpy(&old, buffer, sizeof(struct timespec));
fprintf(stderr, "%u: %lli", i, timedelta(&old, &now));
i++;
}
XlapTimestampTableDumpHeader(out_desc);
XlapTimestampTableDump(out_desc, ts_data_packet, tstable_data);
XlapTimestampTableDump(out_desc, ts_redundancy_packet, tstable_redundancy);
if (file_output) {
fclose(out_desc);
}
PrrtSocket_close(s);
free(s);
free(tstable_data);
free(tstable_redundancy);
pthread_exit(NULL);
return 0;
error:
return -1;
}
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <argp.h>
#include <assert.h>
#include "util/dbg.h"
#include "proto/socket.h"
static char doc[] = "PRRT Sender";
static struct argp_option options[] = {
{"target", 't', "HOST", 0, "Target Host" },
{"port", 'p', "PORT", 0, "Target Port" },
{"local port", 'l', "PORT", 0, "Local Port" },
{"rounds", 'r', "ROUNDS", 0, "Rounds" },
{"output", 'o', "FILE", 0, "Output to FILE instead of standard output" },
{"threadpinning", 'T', 0, 0, "Enable thread pinning"},
{ 0 }
};
static struct arguments
{
char* target;
uint16_t port;
uint16_t local_port;
uint16_t rounds;
char* outfile;
bool thread_pinning;
};
static char args_doc[] = "";
static error_t parse_opt (int key, char *arg, struct argp_state *state)
{
struct arguments *arguments = state->input;
char* pEnd;
switch (key)
{
case 't':
arguments->target = arg;
break;
case 'p':
arguments->port = (uint16_t) strtol(arg, &pEnd, 10);
break;
case 'l':
arguments->local_port = (uint16_t) strtol(arg, &pEnd, 10);
break;
case 'r':
arguments->rounds = (uint16_t) strtol(arg, &pEnd, 10);
break;
case 'o':
arguments->outfile = arg;
break;
case 'T':
arguments->thread_pinning = true;
break;
case ARGP_KEY_END:
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
int main(int argc, char **argv) {
struct argp argp = { options, parse_opt, args_doc, doc };
struct arguments arguments = {
.target = "127.0.0.1",
.port = 5000,
.local_port = 6000,
.rounds = 127,
.outfile = "-",
.thread_pinning = false,
};
argp_parse (&argp, argc, argv, 0, 0, &arguments);
bool file_output = false;
FILE *out_desc = stdout;
if (strcmp(arguments.outfile, "-") != 0) {
file_output = true;
out_desc = fopen(arguments.outfile, "w");
}
uint32_t rounds = arguments.rounds;
#ifdef XLAP
if (rounds >= TS_ROWS) {
printf("Sender: Too many rounds for use with XLAP (max: %d).\n", TS_ROWS-1);
return -1;
}
#endif
PrrtSocket *s = PrrtSocket_create(true, 10 * 1000 * 1000);
check(s != NULL, "Socket create failed.");
if(arguments.thread_pinning) {
PrrtSocket_enable_thread_pinning(s);
}
check(PrrtSocket_bind(s, "0.0.0.0", arguments.local_port), "bind failed");
//PrrtSocket_set_coding_parameters(s, 1, 1); // comment this line to re-enable coding.
PrrtSocket_connect(s, arguments.target, arguments.port);
XlapTimestampTable *tstable_data = malloc(sizeof(XlapTimestampTable));
XlapTimestampTable *tstable_redundancy = malloc(sizeof(XlapTimestampTable));
check(tstable_data != NULL, "malloc failed");
check(tstable_redundancy != NULL, "malloc failed");
XlapTimestampTableInstall(s, ts_data_packet, tstable_data);
XlapTimestampTableInstall(s, ts_redundancy_packet, tstable_redundancy);
uint32_t j = 0;
char buf[MAX_PAYLOAD_LENGTH];
memset(buf, 0x0, sizeof(buf));
assert(sizeof(buf) >= sizeof(struct timespec));
while (j < rounds) {
struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
memcpy(buf, &now, sizeof(struct timespec));
PrrtSocket_send(s, (unsigned char *) buf, sizeof(buf));
j++;
// Send every 100us, as this is a sensible packet interval.
//usleep_nano(100);
}
sleep_nano(10);
XlapTimestampTableDumpHeader(out_desc);
XlapTimestampTableDump(out_desc, ts_data_packet, tstable_data);
XlapTimestampTableDump(out_desc, ts_redundancy_packet, tstable_redundancy);
if (file_output) {
fflush(out_desc);
fclose(out_desc);
}
PrrtSocket_close(s);
free(s);
free(tstable_data);
free(tstable_redundancy);
return 0;
error:
return -1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment