Loading prrt/CMakeLists.txt +4 −0 Original line number Diff line number Diff line Loading @@ -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}) prrt/time-receiver.c 0 → 100644 +155 −0 Original line number Diff line number Diff line #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; } prrt/time-sender.c 0 → 100644 +152 −0 Original line number Diff line number Diff line #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; } Loading
prrt/CMakeLists.txt +4 −0 Original line number Diff line number Diff line Loading @@ -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})
prrt/time-receiver.c 0 → 100644 +155 −0 Original line number Diff line number Diff line #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; }
prrt/time-sender.c 0 → 100644 +152 −0 Original line number Diff line number Diff line #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; }