Backup added
							parent
							
								
									55d3a9baa3
								
							
						
					
					
						commit
						583d6fdae0
					
				| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					#include "ControlledQueue.h"
 | 
				
			||||||
 | 
					#include <chrono>
 | 
				
			||||||
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ControlledQueue::ControlledQueue(uint32_t maxSize, int timeoutMicroseconds) : m_maxSize(maxSize), m_timeoutMicroseconds(timeoutMicroseconds) {;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ControlledQueue::put(Fragment fragment) {
 | 
				
			||||||
 | 
					    std::unique_lock<std::mutex> lk(m_mtx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					        This while synthax is explicitly used to avoid unwanted spurious awakenings.
 | 
				
			||||||
 | 
					        I'm keeping only the wait with not timeout to transmit backpressure to the upper reading thread, which blocks.
 | 
				
			||||||
 | 
					        Since that thread has locked the mutex corresponding to the fd, basically the whole fd is blocked.
 | 
				
			||||||
 | 
					        That way I can tranmit backpressure with TCP to the sending client.
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    while (! (m_queue.size() < m_maxSize) ) {
 | 
				
			||||||
 | 
					        m_cv.wait(lk);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    m_queue.push(fragment);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lk.unlock();
 | 
				
			||||||
 | 
					    m_cv.notify_all();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					    Basically here a simple string exception is thrown if the wait terminates because of timeout and not because someone has inserted an element.
 | 
				
			||||||
 | 
					    That way it can be catched from the main program that can set the error code accordingly.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					Fragment ControlledQueue::get() {
 | 
				
			||||||
 | 
					    std::unique_lock<std::mutex> lk(m_mtx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ( !m_cv.wait_for(lk, std::chrono::microseconds(m_timeoutMicroseconds), !(m_queue.empty())) ) {
 | 
				
			||||||
 | 
					        throw "Get Timeout";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Fragment fragment = m_queue.front();
 | 
				
			||||||
 | 
					    m_queue.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lk.unlock();
 | 
				
			||||||
 | 
					    m_cv.notify_all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return fragment;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					#include <condition_variable>
 | 
				
			||||||
 | 
					#include <queue>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "fragment_dataformat.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ControlledQueue {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        ControlledQueue(uint32_t maxSize, int timeoutMicroseconds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void put(Fragment fragment);
 | 
				
			||||||
 | 
					        Fragment get();
 | 
				
			||||||
 | 
					        bool empty() { return m_queue.empty(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        std::mutex m_mtx;
 | 
				
			||||||
 | 
					        std::condition_variable m_cv;
 | 
				
			||||||
 | 
					        uint32_t m_maxSize;
 | 
				
			||||||
 | 
					        std::queue<Fragment> m_queue;
 | 
				
			||||||
 | 
					        int m_timeoutMicroseconds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"folders": [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"path": ".."
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"settings": {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					# Event Builder Project
 | 
				
			||||||
 | 
					This repo contains the code for a simple Event Builder inspired by ATLAS event format. It's a project for the exam "Tecniche Digitali di Acquisizione Dati" @UNIPV.
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -0,0 +1,244 @@
 | 
				
			||||||
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					#include <csignal>
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include <cstdio>
 | 
				
			||||||
 | 
					#include <cstdlib>
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					#include <sys/select.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <queue>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int makeSocket() {
 | 
				
			||||||
 | 
					    int sockfd;
 | 
				
			||||||
 | 
					    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 | 
				
			||||||
 | 
					        perror("socket failed");
 | 
				
			||||||
 | 
					        exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return sockfd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void bindSocketPort(int server_fd, int port) {
 | 
				
			||||||
 | 
					    struct sockaddr_in localAddr;
 | 
				
			||||||
 | 
					    localAddr.sin_family = AF_INET;
 | 
				
			||||||
 | 
					    localAddr.sin_addr.s_addr = INADDR_ANY;
 | 
				
			||||||
 | 
					    localAddr.sin_port = htons(port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (bind(server_fd, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) {
 | 
				
			||||||
 | 
					        perror("bind failed");
 | 
				
			||||||
 | 
					        exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf("FD %d bound to port %d\n", server_fd, port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void startListening(int server_fd) {
 | 
				
			||||||
 | 
					    if (listen(server_fd, 3) < 0) {
 | 
				
			||||||
 | 
					        perror("listen");
 | 
				
			||||||
 | 
					        exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf("FD %d listening to new connections\n", server_fd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int acceptConnection(int server_fd) {
 | 
				
			||||||
 | 
					    int client_fd;
 | 
				
			||||||
 | 
					    struct sockaddr_in remoteAddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    size_t addrlen = sizeof(remoteAddr);
 | 
				
			||||||
 | 
					    if ((client_fd = accept(server_fd, (struct sockaddr *)&remoteAddr, (socklen_t *)&addrlen)) < 0) {
 | 
				
			||||||
 | 
					        perror("accept");
 | 
				
			||||||
 | 
					        exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printf("Connection from host %s, port %d, FD %d\n", inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port), client_fd);
 | 
				
			||||||
 | 
					    return client_fd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void term_handler(int signal) {
 | 
				
			||||||
 | 
					    printf("Terminated, received SIGNAL %d", signal);
 | 
				
			||||||
 | 
					    exit(EXIT_SUCCESS);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					int main(int argc, char const *argv[]) {
 | 
				
			||||||
 | 
					    signal(SIGTERM, term_handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (argc != 2) {
 | 
				
			||||||
 | 
					        printf("Usage: %s portNumber \n", argv[0]);
 | 
				
			||||||
 | 
					        exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    int port = atoi(argv[1]);
 | 
				
			||||||
 | 
					    printf("Start socket port %d\n", port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int server_fd = makeSocket();
 | 
				
			||||||
 | 
					    bindSocketPort(server_fd, port);
 | 
				
			||||||
 | 
					    startListening(server_fd);
 | 
				
			||||||
 | 
					    int client_fd = acceptConnection(server_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (true) {
 | 
				
			||||||
 | 
					        uint32_t word;
 | 
				
			||||||
 | 
					        ssize_t bytes = read(client_fd, &word, 4);
 | 
				
			||||||
 | 
					        if (bytes != 4) {
 | 
				
			||||||
 | 
					            perror("Receive failed");
 | 
				
			||||||
 | 
					            exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        printf("[RICEVUTO]\t0x%x\n", word);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TRUE   1 
 | 
				
			||||||
 | 
					#define FALSE  0 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char const *argv[]) {
 | 
				
			||||||
 | 
					    signal(SIGTERM, term_handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (argc != 2) {
 | 
				
			||||||
 | 
					        printf("Usage: %s portNumber \n", argv[0]);
 | 
				
			||||||
 | 
					        exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    int port = atoi(argv[1]);
 | 
				
			||||||
 | 
					    printf("Start socket port %d\n", port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int opt = TRUE;  
 | 
				
			||||||
 | 
					    int master_socket , addrlen , new_socket , client_socket[30] , 
 | 
				
			||||||
 | 
					          max_clients = 30 , activity, i , valread , sd;  
 | 
				
			||||||
 | 
					    int max_sd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //set of socket descriptors 
 | 
				
			||||||
 | 
					    fd_set readfds;  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //initialise all client_socket[] to 0 so not checked 
 | 
				
			||||||
 | 
					    for (i = 0; i < max_clients; i++)  
 | 
				
			||||||
 | 
					    {  
 | 
				
			||||||
 | 
					        client_socket[i] = 0;  
 | 
				
			||||||
 | 
					    }  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    master_socket = makeSocket();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //set master socket to allow multiple connections , 
 | 
				
			||||||
 | 
					    //this is just a good habit, it will work without this 
 | 
				
			||||||
 | 
					    if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, 
 | 
				
			||||||
 | 
					          sizeof(opt)) < 0 )  
 | 
				
			||||||
 | 
					    {  
 | 
				
			||||||
 | 
					        perror("setsockopt");  
 | 
				
			||||||
 | 
					        exit(EXIT_FAILURE);  
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bindSocketPort(master_socket, port);
 | 
				
			||||||
 | 
					    startListening(master_socket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (true) {
 | 
				
			||||||
 | 
					        //clear the socket set 
 | 
				
			||||||
 | 
					        FD_ZERO(&readfds);  
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					        //add master socket to set 
 | 
				
			||||||
 | 
					        FD_SET(master_socket, &readfds);  
 | 
				
			||||||
 | 
					        max_sd = master_socket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //add child sockets to set 
 | 
				
			||||||
 | 
					        for ( i = 0 ; i < max_clients ; i++)  
 | 
				
			||||||
 | 
					        {  
 | 
				
			||||||
 | 
					            //socket descriptor 
 | 
				
			||||||
 | 
					            sd = client_socket[i];  
 | 
				
			||||||
 | 
					                 
 | 
				
			||||||
 | 
					            //if valid socket descriptor then add to read list 
 | 
				
			||||||
 | 
					            if(sd > 0)  
 | 
				
			||||||
 | 
					                FD_SET( sd , &readfds);  
 | 
				
			||||||
 | 
					                 
 | 
				
			||||||
 | 
					            //highest file descriptor number, need it for the select function 
 | 
				
			||||||
 | 
					            if(sd > max_sd)  
 | 
				
			||||||
 | 
					                max_sd = sd;  
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //wait for an activity on one of the sockets , timeout is NULL , 
 | 
				
			||||||
 | 
					        //so wait indefinitely 
 | 
				
			||||||
 | 
					        activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((activity < 0) && (errno!=EINTR))  
 | 
				
			||||||
 | 
					        {  
 | 
				
			||||||
 | 
					            printf("select error");  
 | 
				
			||||||
 | 
					        } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //If something happened on the master socket , 
 | 
				
			||||||
 | 
					        //then its an incoming connection 
 | 
				
			||||||
 | 
					        if (FD_ISSET(master_socket, &readfds))  
 | 
				
			||||||
 | 
					        {  
 | 
				
			||||||
 | 
					            new_socket = acceptConnection(master_socket);
 | 
				
			||||||
 | 
					                 
 | 
				
			||||||
 | 
					            //add new socket to array of sockets 
 | 
				
			||||||
 | 
					            for (i = 0; i < max_clients; i++)  
 | 
				
			||||||
 | 
					            {  
 | 
				
			||||||
 | 
					                //if position is empty 
 | 
				
			||||||
 | 
					                if( client_socket[i] == 0 )  
 | 
				
			||||||
 | 
					                {  
 | 
				
			||||||
 | 
					                    client_socket[i] = new_socket;  
 | 
				
			||||||
 | 
					                    printf("Adding to list of sockets as %d\n" , i);  
 | 
				
			||||||
 | 
					                         
 | 
				
			||||||
 | 
					                    break;  
 | 
				
			||||||
 | 
					                }  
 | 
				
			||||||
 | 
					            }  
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //else its some IO operation on some other socket
 | 
				
			||||||
 | 
					        for (i = 0; i < max_clients; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            sd = client_socket[i];  
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (FD_ISSET( sd , &readfds))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                //Check if it was for closing , and also read the 
 | 
				
			||||||
 | 
					                //incoming message
 | 
				
			||||||
 | 
					                uint32_t word;
 | 
				
			||||||
 | 
					                if ((valread = recv( sd , &word, 4, 0)) == 0)  
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    struct sockaddr_in address;
 | 
				
			||||||
 | 
					                    int addrlen;
 | 
				
			||||||
 | 
					                    //Somebody disconnected , get his details and print 
 | 
				
			||||||
 | 
					                    getpeername(sd , (struct sockaddr*)&address , \
 | 
				
			||||||
 | 
					                        (socklen_t*)&addrlen);  
 | 
				
			||||||
 | 
					                    printf("Host disconnected , ip %s , port %d \n" , 
 | 
				
			||||||
 | 
					                          inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    printf("Disconnected fd %d", sd);
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    //Close the socket and mark as 0 in list for reuse
 | 
				
			||||||
 | 
					                    close( sd );
 | 
				
			||||||
 | 
					                    client_socket[i] = 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                //Echo back the message that came in 
 | 
				
			||||||
 | 
					                else 
 | 
				
			||||||
 | 
					                {  
 | 
				
			||||||
 | 
					                    printf("[RICEVUTO]\t0x%x FROM %d\n", word, sd);
 | 
				
			||||||
 | 
					                }  
 | 
				
			||||||
 | 
					            }  
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int client_fd = acceptConnection(server_fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (true) {
 | 
				
			||||||
 | 
					        uint32_t word;
 | 
				
			||||||
 | 
					        ssize_t bytes = read(client_fd, &word, 4);
 | 
				
			||||||
 | 
					        if (bytes != 4) {
 | 
				
			||||||
 | 
					            perror("Receive failed");
 | 
				
			||||||
 | 
					            exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        printf("[RICEVUTO]\t0x%x\n", word);
 | 
				
			||||||
 | 
					    }*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,85 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstddef>
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FRAGMENT_HEADER_MARKER 0xee1234ee
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct Header {
 | 
				
			||||||
 | 
					    uint32_t startOfHeaderMarker = FRAGMENT_HEADER_MARKER;
 | 
				
			||||||
 | 
					    uint32_t headerSize;
 | 
				
			||||||
 | 
					    uint32_t fragmentSize;
 | 
				
			||||||
 | 
					    uint32_t sourceIdentifier;
 | 
				
			||||||
 | 
					    uint32_t runNumber;
 | 
				
			||||||
 | 
					    uint32_t detectorEventNumber;
 | 
				
			||||||
 | 
					    uint32_t numberOfStatusElements;
 | 
				
			||||||
 | 
					    uint32_t *statusElementsArray;
 | 
				
			||||||
 | 
					    /*friend std::ostream& operator <<(std::ostream& os, Header const& header)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return os << std::setw(8) << std::setfill('0') << header.startOfHeaderMarker << '\n'
 | 
				
			||||||
 | 
					                  << std::setw(8) << std::setfill('0') << header.headerSize << '\n'
 | 
				
			||||||
 | 
					                  << std::setw(8) << std::setfill('0') << header.fragmentSize << '\n'
 | 
				
			||||||
 | 
					                  << std::setw(8) << std::setfill('0') << header.runNumber << '\n'
 | 
				
			||||||
 | 
					                  << std::setw(8) << std::setfill('0') << header.detectorEventNumber << '\n'
 | 
				
			||||||
 | 
					                  << std::setw(8) << std::setfill('0') << header.numberOfStatusElements << '\n';
 | 
				
			||||||
 | 
					    }*/
 | 
				
			||||||
 | 
					} Header;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct Fragment {
 | 
				
			||||||
 | 
					    Header header;
 | 
				
			||||||
 | 
					    uint32_t *payloadElements;
 | 
				
			||||||
 | 
					} Fragment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ERROR_CODES {
 | 
				
			||||||
 | 
					    INCORRECT_ERROR = (1 << 0),
 | 
				
			||||||
 | 
					    CORRUPTED_ERROR = (1 << 1),
 | 
				
			||||||
 | 
					    MISSING_DATA_ERROR = (1 << 2),
 | 
				
			||||||
 | 
					    TIMEOUT_ERROR = (1 << 3)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void encode_header(uint32_t *buffer, const Header &header) {
 | 
				
			||||||
 | 
					    buffer[0] = header.startOfHeaderMarker;
 | 
				
			||||||
 | 
					    buffer[1] = header.headerSize;
 | 
				
			||||||
 | 
					    buffer[2] = header.fragmentSize;
 | 
				
			||||||
 | 
					    buffer[3] = header.sourceIdentifier;
 | 
				
			||||||
 | 
					    buffer[4] = header.runNumber;
 | 
				
			||||||
 | 
					    buffer[5] = header.detectorEventNumber;
 | 
				
			||||||
 | 
					    buffer[6] = header.numberOfStatusElements;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::memcpy(&buffer[7], header.statusElementsArray, header.numberOfStatusElements * sizeof(uint32_t));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void encode_fragment(uint32_t *buffer, const Fragment &fragment){
 | 
				
			||||||
 | 
					    encode_header(buffer, fragment.header);
 | 
				
			||||||
 | 
					    std::memcpy(&buffer[fragment.header.headerSize], fragment.payloadElements, (fragment.header.fragmentSize - fragment.header.headerSize) * sizeof(uint32_t));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fragment decode_fragment(uint32_t *buffer) {
 | 
				
			||||||
 | 
					    Fragment fragment;
 | 
				
			||||||
 | 
					    fragment.header.startOfHeaderMarker = buffer[0];
 | 
				
			||||||
 | 
					    fragment.header.headerSize = buffer[1];
 | 
				
			||||||
 | 
					    fragment.header.fragmentSize = buffer[2];
 | 
				
			||||||
 | 
					    fragment.header.sourceIdentifier = buffer[3];
 | 
				
			||||||
 | 
					    fragment.header.runNumber = buffer[4];
 | 
				
			||||||
 | 
					    fragment.header.detectorEventNumber = buffer[5];
 | 
				
			||||||
 | 
					    fragment.header.numberOfStatusElements = buffer[6];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t nStatusElements = fragment.header.numberOfStatusElements;
 | 
				
			||||||
 | 
					    fragment.header.statusElementsArray = new uint32_t[nStatusElements];
 | 
				
			||||||
 | 
					    for (int i = 1; i <= nStatusElements; i++) {
 | 
				
			||||||
 | 
					        fragment.header.statusElementsArray[6+i] = buffer[6+i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t payload_size =  fragment.header.fragmentSize - fragment.header.headerSize;
 | 
				
			||||||
 | 
					    fragment.payloadElements = new uint32_t[payload_size];
 | 
				
			||||||
 | 
					    for (int i = 1; i <= payload_size; i++) {
 | 
				
			||||||
 | 
					        fragment.payloadElements[6+nStatusElements+i] = buffer[6+nStatusElements+i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return fragment;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "fragment_dataformat.h"
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FULL_EVENT_HEADER_MARKER 0xaa1234aa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct FullEvent {
 | 
				
			||||||
 | 
					    uint32_t startOfHeaderMarker = FULL_EVENT_HEADER_MARKER;
 | 
				
			||||||
 | 
					    uint32_t headerSize;
 | 
				
			||||||
 | 
					    uint32_t eventSize;
 | 
				
			||||||
 | 
					    uint32_t runNumber;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Fragment *fragmentsArray;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}FullEvent;
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,161 @@
 | 
				
			||||||
 | 
					#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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					echo "Usage: $0 host port runNumber numberOfProviders"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ $# -eq 4 ]
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
					    echo "Selected host: $1:$2 runNumber: $3 numberOfProviders: $4"
 | 
				
			||||||
 | 
					    for i in $(seq 1 $4);
 | 
				
			||||||
 | 
					    do
 | 
				
			||||||
 | 
					        echo "Spawning provider number $i"
 | 
				
			||||||
 | 
					        ./prov.out $1 $2 $3 &
 | 
				
			||||||
 | 
					    done
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
| 
						 | 
					@ -11,4 +11,3 @@ do
 | 
				
			||||||
    kill -15 `pidof ./prov.out`
 | 
					    kill -15 `pidof ./prov.out`
 | 
				
			||||||
    sleep 1
 | 
					    sleep 1
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue