161 lines
4.9 KiB
C++
161 lines
4.9 KiB
C++
#include <algorithm>
|
|
#include <arpa/inet.h>
|
|
#include <cmath>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <ctime>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <netinet/in.h>
|
|
#include <random>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <csignal>
|
|
|
|
|
|
#include "fragment_dataformat.h"
|
|
|
|
#define MIN_FRAGMENTS 0
|
|
#define MAX_FRAGMENTS 100
|
|
|
|
|
|
/*
|
|
int rndError(float p){
|
|
float rndFloat = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
|
return rndFloat < p;
|
|
}*/
|
|
|
|
|
|
int makeSocket() {
|
|
int sockfd;
|
|
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
|
perror("socket failed");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
return sockfd;
|
|
}
|
|
|
|
void connectTo(int sock, const char* host, int port) {
|
|
struct sockaddr_in serv_addr;
|
|
serv_addr.sin_family = AF_INET;
|
|
serv_addr.sin_addr.s_addr = inet_addr(host);
|
|
serv_addr.sin_port = htons(port);
|
|
|
|
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
|
|
perror("Connection failed");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
printf("Connected to %s: %d\n", host, port);
|
|
}
|
|
|
|
|
|
void term_handler(int signal) {
|
|
printf("Terminated, received SIGNAL %d", signal);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
|
signal(SIGTERM, term_handler);
|
|
signal(SIGINT, term_handler);
|
|
|
|
//will use it later to obtain random number from hardware
|
|
std::random_device rd;
|
|
std::mt19937 generator(42);
|
|
std::discrete_distribution<uint8_t> discrete_distr({0.9, 0.1});
|
|
std::normal_distribution<float> normal_distr(25., 10.);
|
|
std::uniform_int_distribution<uint32_t> unif_int_distib;
|
|
std::uniform_real_distribution<float> unif_float_distrib(0.5, 2);
|
|
|
|
//commenting all old_style generation
|
|
//srand (static_cast <unsigned> (42));
|
|
|
|
bool out_condition = true;
|
|
uint32_t event_number = 0;
|
|
|
|
uint32_t run_number = 0;
|
|
uint32_t source_id = 0;
|
|
|
|
if (argc != 5) {
|
|
printf("Usage %s host portNumber sourceId runNumber\n", argv[0]);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
const char* host = argv[1];
|
|
int port = atoi(argv[2]);
|
|
source_id = atoi(argv[3]);
|
|
run_number = atoi(argv[4]);
|
|
|
|
int socket = makeSocket();
|
|
connectTo(socket, host, port);
|
|
|
|
while (true) {
|
|
Header header;
|
|
header.sourceIdentifier = source_id;
|
|
header.runNumber = run_number;
|
|
header.detectorEventNumber = event_number;
|
|
event_number++;
|
|
header.numberOfStatusElements = 0;
|
|
//if swap to old style just change with function above and prob 0.1 for 1
|
|
uint8_t incorrectError = discrete_distr(generator);
|
|
uint8_t corruptedError = discrete_distr(generator);
|
|
uint8_t missingDataError = discrete_distr(generator);
|
|
uint8_t timeoutError = discrete_distr(generator);
|
|
|
|
uint32_t firstStatusElement = 0x0;
|
|
|
|
if (incorrectError) firstStatusElement |= INCORRECT_ERROR;
|
|
if (corruptedError) firstStatusElement |= CORRUPTED_ERROR;
|
|
if (missingDataError) firstStatusElement |= MISSING_DATA_ERROR;
|
|
if (timeoutError) firstStatusElement |= TIMEOUT_ERROR;
|
|
|
|
if (firstStatusElement != 0x0) {
|
|
header.numberOfStatusElements = 1;
|
|
header.statusElementsArray = new uint32_t[header.numberOfStatusElements];
|
|
header.statusElementsArray[0] = firstStatusElement;
|
|
}
|
|
|
|
uint32_t payload_size = std::max(std::min(static_cast<int>(std::round(normal_distr(generator))), MAX_FRAGMENTS), MIN_FRAGMENTS);
|
|
header.headerSize = 7 + header.numberOfStatusElements;
|
|
header.fragmentSize = header.headerSize + payload_size;
|
|
|
|
Fragment fragment;
|
|
fragment.header = header;
|
|
fragment.payloadElements = new uint32_t[payload_size];
|
|
for (uint32_t i = 0; i < payload_size; i++) {
|
|
fragment.payloadElements[i] = unif_int_distib(generator);
|
|
}
|
|
|
|
uint32_t buffer[header.fragmentSize];
|
|
encode_fragment(buffer, fragment);
|
|
ssize_t bytes = send(socket, reinterpret_cast<char*>(buffer), sizeof(buffer), 0);
|
|
if (bytes != header.fragmentSize * sizeof(uint32_t)) {
|
|
perror("Send failed: num bytes not matching");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
|
|
//std::cout << std::hex << std::setw(8) << std::setfill('0');
|
|
////std::cout << fragment.header;
|
|
//for (uint8_t i = 0; i < fragment.header.numberOfStatusElements; i++) {
|
|
// std::cout << "status element " << std::setw(8) << std::setfill('0') << fragment.header.statusElementsArray[i] << std::endl;
|
|
//}
|
|
//for (uint32_t i = 0; i < payload_size; i++) {
|
|
// std::cout << "payload element " << std::setw(8) << std::setfill('0') << fragment.payloadElements[i] << std::endl;
|
|
//}
|
|
//std::cout << std::endl;
|
|
|
|
if (header.numberOfStatusElements > 0){
|
|
delete [] fragment.header.statusElementsArray;
|
|
}
|
|
delete [] fragment.payloadElements;
|
|
|
|
|
|
sleep(unif_float_distrib(generator));
|
|
}
|
|
|
|
return 0;
|
|
} |